summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÂngelo Andrade Cirino <[email protected]>2022-01-10 10:23:17 -0300
committerÂngelo Andrade Cirino <[email protected]>2022-01-10 10:23:17 -0300
commited0c0c5e0249aa966ea7061b30710abdd0b09d87 (patch)
tree2a51c869a3aea1a093ed569e749bdf0465634a6c
parent885d00da8caf74aeed758d030b9a1b50d9078e1f (diff)
parent2431dd7e6142ff98b55741cfd4de4d2e69f4f8b5 (diff)
Merged from upstream/master
-rw-r--r--.appveyor.yml125
-rw-r--r--.github/workflows/archlinux.yml5
-rw-r--r--.github/workflows/debian_mips64.yml4
-rw-r--r--.github/workflows/fedora.yml3
-rw-r--r--.github/workflows/freebsd.yml7
-rw-r--r--.github/workflows/linux.yml19
-rw-r--r--.github/workflows/linux_luajit.yml36
-rw-r--r--.github/workflows/macos.yml3
-rw-r--r--.github/workflows/msys2_mingw.yml5
-rw-r--r--.github/workflows/ubuntu_arm.yml4
-rw-r--r--.github/workflows/ubuntu_arm64.yml4
-rw-r--r--.github/workflows/windows.yml23
-rw-r--r--.github/workflows/windows_luajit.yml121
-rw-r--r--.gitignore12
-rw-r--r--.gitmodules3
-rw-r--r--CHANGELOG.md260
-rw-r--r--NOTICE.md8
-rw-r--r--README.md93
-rw-r--r--README_zh.md91
-rw-r--r--core/makefile19
-rw-r--r--core/project.mak6
-rw-r--r--core/src/demo/makefile10
-rw-r--r--core/src/demo/xmake.rc2
-rw-r--r--core/src/lcurses/lcurses.c30
-rw-r--r--core/src/lcurses/makefile9
-rw-r--r--core/src/lcurses/xmake.lua2
-rw-r--r--core/src/lua-cjson/makefile10
-rw-r--r--core/src/lua-cjson/xmake.lua2
m---------core/src/lua/lua0
-rw-r--r--core/src/lua/makefile87
-rw-r--r--core/src/lua/xmake.lua31
-rw-r--r--core/src/luajit/xmake.lua5
-rw-r--r--core/src/makefile10
m---------core/src/sv/sv0
m---------core/src/tbox/tbox0
-rw-r--r--core/src/xmake/engine.c80
-rw-r--r--core/src/xmake/io/file_open.c6
-rw-r--r--core/src/xmake/io/file_write.c38
-rw-r--r--core/src/xmake/io/pipe_read.c2
-rw-r--r--core/src/xmake/io/pipe_write.c6
-rw-r--r--core/src/xmake/io/prefix.h1
-rw-r--r--core/src/xmake/io/socket_recv.c2
-rw-r--r--core/src/xmake/io/socket_recvfrom.c2
-rw-r--r--core/src/xmake/io/socket_send.c6
-rw-r--r--core/src/xmake/io/socket_sendfile.c4
-rw-r--r--core/src/xmake/io/socket_sendto.c2
-rw-r--r--core/src/xmake/io/stdfile.c2
-rw-r--r--core/src/xmake/libc/byteof.c58
-rw-r--r--core/src/xmake/libc/dataptr.c52
-rw-r--r--core/src/xmake/libc/free.c46
-rw-r--r--core/src/xmake/libc/malloc.c48
-rw-r--r--core/src/xmake/libc/memcpy.c49
-rw-r--r--core/src/xmake/libc/memset.c49
-rw-r--r--core/src/xmake/libc/prefix.h44
-rw-r--r--core/src/xmake/libc/setbyte.c62
-rw-r--r--core/src/xmake/libc/strndup.c54
-rw-r--r--core/src/xmake/makefile26
-rw-r--r--core/src/xmake/os/args.c2
-rw-r--r--core/src/xmake/os/find.c4
-rw-r--r--core/src/xmake/prefix.h28
-rw-r--r--core/src/xmake/process/open.c6
-rw-r--r--core/src/xmake/process/openv.c10
-rw-r--r--core/src/xmake/sandbox/interactive.c16
-rw-r--r--core/src/xmake/semver/select.c26
-rw-r--r--core/src/xmake/string/endswith.c1
-rw-r--r--core/src/xmake/tty/prefix.h32
-rw-r--r--core/src/xmake/tty/term_mode.c73
-rw-r--r--core/src/xmake/winos/registry_keys.c2
-rw-r--r--core/src/xmake/winos/short_path.c79
-rw-r--r--core/src/xmake/xmake.config.h.in2
-rw-r--r--core/src/xmake/xmake.lua3
-rw-r--r--core/xmake.lua12
-rw-r--r--makefile10
-rwxr-xr-xscripts/archlinux/PKGBUILD9
-rwxr-xr-xscripts/get.ps113
-rwxr-xr-xscripts/get.sh36
-rw-r--r--scripts/installer.nsi9
-rw-r--r--scripts/register-virtualenvs.sh72
-rw-r--r--scripts/rpmbuild/SPECS/xmake.spec26
-rwxr-xr-xscripts/xrepo.bat52
-rw-r--r--scripts/xrepo.ps116
-rw-r--r--tests/apis/add_configfiles/config.h.in3
-rw-r--r--tests/apis/add_configfiles/xmake.lua1
-rw-r--r--tests/apis/check_xxx/config.h.in18
-rw-r--r--tests/apis/check_xxx/foo.c6
-rw-r--r--tests/apis/check_xxx/main.c1
-rw-r--r--tests/apis/check_xxx/xmake.lua81
-rw-r--r--tests/apis/rules/xmake.lua2
-rw-r--r--tests/apis/set_toolchains/xmake.lua1
-rw-r--r--tests/modules/heap/test.lua3
-rwxr-xr-xtests/modules/semver/test.lua8
-rw-r--r--tests/modules/string/serialize/test.lua5
-rw-r--r--tests/modules/table/test.lua11
-rw-r--r--tests/projects/c++/modules/class/src/hello.mpp3
-rw-r--r--tests/projects/c++/modules/class/src/hello_impl.cpp7
-rw-r--r--tests/projects/c++/modules/dependence/src/hello.mpp13
-rw-r--r--tests/projects/c++/modules/dependence/src/hello_impl.cpp6
-rw-r--r--tests/projects/c++/modules/dependence2/src/bar.mpp8
-rw-r--r--tests/projects/c++/modules/dependence2/src/cat.mpp8
-rw-r--r--tests/projects/c++/modules/dependence2/src/foo.mpp13
-rw-r--r--tests/projects/c++/modules/dependence2/src/main.cpp10
-rw-r--r--tests/projects/c++/modules/dependence2/src/zoo.mpp8
-rw-r--r--tests/projects/c++/modules/dependence2/xmake.lua4
-rw-r--r--tests/projects/c++/modules/hello/src/hello.mpp7
-rw-r--r--tests/projects/c++/modules/hello/src/main.cpp2
-rw-r--r--tests/projects/c++/modules/impl_unit/src/hello_impl.cpp4
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/hello.mpp6
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/say.mpp6
-rw-r--r--tests/projects/c++/modules/partitions/src/main.cpp11
-rw-r--r--tests/projects/c++/modules/partitions/src/math.math1.mpp5
-rw-r--r--tests/projects/c++/modules/partitions/src/math.math2.mpp7
-rw-r--r--tests/projects/c++/modules/partitions/src/math.mpp4
-rw-r--r--tests/projects/c++/modules/partitions/xmake.lua4
-rw-r--r--tests/projects/c++/modules/staticlib/src/main.cpp8
-rw-r--r--tests/projects/c++/modules/staticlib/src/mod.cpp7
-rw-r--r--tests/projects/c++/modules/staticlib/src/mod.mpp5
-rw-r--r--tests/projects/c++/modules/staticlib/xmake.lua10
-rw-r--r--tests/projects/c++/modules/submodules/src/main.cpp10
-rw-r--r--tests/projects/c++/modules/submodules/src/math.math1.mpp5
-rw-r--r--tests/projects/c++/modules/submodules/src/math.math2.mpp7
-rw-r--r--tests/projects/c++/modules/submodules/src/math.mpp4
-rw-r--r--tests/projects/c++/modules/submodules/xmake.lua4
-rw-r--r--tests/projects/c++/protobuf/src/main.cpp3
-rw-r--r--tests/projects/c++/unity_build/src/bar/test4.cpp12
-rw-r--r--tests/projects/c++/unity_build/src/bar/test5.cpp13
-rw-r--r--tests/projects/c++/unity_build/src/bar/test6.cpp8
-rw-r--r--tests/projects/c++/unity_build/src/foo/test.cpp8
-rw-r--r--tests/projects/c++/unity_build/src/foo/test2.cpp8
-rw-r--r--tests/projects/c++/unity_build/src/header.h27
-rw-r--r--tests/projects/c++/unity_build/src/header2.h0
-rw-r--r--tests/projects/c++/unity_build/src/main.cpp8
-rw-r--r--tests/projects/c++/unity_build/src/test.c4
-rw-r--r--tests/projects/c++/unity_build/src/test7.cpp8
-rw-r--r--tests/projects/c++/unity_build/src/test8.cpp8
-rw-r--r--tests/projects/c++/unity_build/test.lua6
-rw-r--r--tests/projects/c++/unity_build/xmake.lua9
-rw-r--r--tests/projects/c/headeronly/src/foo.h9
-rw-r--r--tests/projects/c/headeronly/test.lua6
-rw-r--r--tests/projects/c/headeronly/xmake.lua9
-rw-r--r--tests/projects/c/library_with_cmakelists/.gitignore8
-rw-r--r--tests/projects/c/library_with_cmakelists/foo/CMakeLists.txt15
-rw-r--r--tests/projects/c/library_with_cmakelists/foo/src/foo.c6
-rw-r--r--tests/projects/c/library_with_cmakelists/foo/src/foo.h1
-rw-r--r--tests/projects/c/library_with_cmakelists/src/main.c8
-rw-r--r--tests/projects/c/library_with_cmakelists/test.lua13
-rw-r--r--tests/projects/c/library_with_cmakelists/xmake.lua23
-rw-r--r--tests/projects/c/unity_build/src/bar/test4.c8
-rw-r--r--tests/projects/c/unity_build/src/bar/test5.c8
-rw-r--r--tests/projects/c/unity_build/src/foo/test1.c8
-rw-r--r--tests/projects/c/unity_build/src/foo/test2.c8
-rw-r--r--tests/projects/c/unity_build/src/header.h10
-rw-r--r--tests/projects/c/unity_build/src/main.c7
-rw-r--r--tests/projects/c/unity_build/src/test.cpp4
-rw-r--r--tests/projects/c/unity_build/src/test2.c8
-rw-r--r--tests/projects/c/unity_build/src/test6.c8
-rw-r--r--tests/projects/c/unity_build/src/test7.c8
-rw-r--r--tests/projects/c/unity_build/src/test8.c8
-rw-r--r--tests/projects/c/unity_build/test.lua6
-rw-r--r--tests/projects/c/unity_build/xmake.lua8
-rw-r--r--tests/projects/embed/mdk/hello/src/foo/foo.c4
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/ARMCM3.h126
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armcc.h888
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armclang.h1503
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_compiler.h283
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_version.h39
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/core_cm3.h1943
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/mpu_armv7.h275
-rw-r--r--tests/projects/embed/mdk/hello/src/lib/cmsis/system_ARMCM3.h62
-rw-r--r--tests/projects/embed/mdk/hello/src/main.c6
-rw-r--r--tests/projects/embed/mdk/hello/src/startup_ARMCM3.s172
-rw-r--r--tests/projects/embed/mdk/hello/src/system_ARMCM3.c65
-rw-r--r--tests/projects/embed/mdk/hello/xmake.lua13
-rw-r--r--tests/projects/linux/bpf/minimal/src/minimal.bpf.c (renamed from tests/projects/bpf/minimal/src/minimal.bpf.c)0
-rw-r--r--tests/projects/linux/bpf/minimal/src/minimal.c (renamed from tests/projects/bpf/minimal/src/minimal.c)0
-rw-r--r--tests/projects/linux/bpf/minimal/test.lua (renamed from tests/projects/bpf/minimal/test.lua)0
-rw-r--r--tests/projects/linux/bpf/minimal/xmake.lua (renamed from tests/projects/bpf/minimal/xmake.lua)0
-rw-r--r--tests/projects/linux/driver/hello/src/add.c3
-rw-r--r--tests/projects/linux/driver/hello/src/hello.c23
-rw-r--r--tests/projects/linux/driver/hello/xmake.lua7
-rw-r--r--tests/projects/linux/driver/hello_custom/src/add.c3
-rw-r--r--tests/projects/linux/driver/hello_custom/src/hello.c23
-rw-r--r--tests/projects/linux/driver/hello_custom/xmake.lua6
-rw-r--r--tests/projects/linux/driver/hello_makefile/Makefile15
-rw-r--r--tests/projects/linux/driver/hello_makefile/src/add.c3
-rw-r--r--tests/projects/linux/driver/hello_makefile/src/hello.c23
-rwxr-xr-xtests/projects/nim/console/src/mainbin0 -> 92184 bytes
-rw-r--r--tests/projects/nim/console/src/main.nim1
-rw-r--r--tests/projects/nim/console/xmake.lua5
-rw-r--r--tests/projects/nim/console_with_c/src/foo.c3
-rw-r--r--tests/projects/nim/console_with_c/src/main.nim3
-rw-r--r--tests/projects/nim/console_with_c/xmake.lua10
-rw-r--r--tests/projects/nim/native_package/src/main.nim3
-rw-r--r--tests/projects/nim/native_package/xmake.lua8
-rw-r--r--tests/projects/nim/nimble_package/src/main.nim3
-rw-r--r--tests/projects/nim/nimble_package/xmake.lua8
-rw-r--r--tests/projects/nim/shared_library/src/foo.nim5
-rw-r--r--tests/projects/nim/shared_library/src/main.nim4
-rw-r--r--tests/projects/nim/shared_library/xmake.lua12
-rw-r--r--tests/projects/nim/static_library/src/foo.nim6
-rw-r--r--tests/projects/nim/static_library/src/main.nim3
-rw-r--r--tests/projects/nim/static_library/xmake.lua12
-rw-r--r--tests/projects/objc/metal_app/.gitignore21
-rw-r--r--tests/projects/objc/metal_app/Application/AAPLAppDelegate.h14
-rw-r--r--tests/projects/objc/metal_app/Application/AAPLAppDelegate.m16
-rw-r--r--tests/projects/objc/metal_app/Application/AAPLViewController.h23
-rw-r--r--tests/projects/objc/metal_app/Application/AAPLViewController.m39
-rw-r--r--tests/projects/objc/metal_app/Application/iOS/Base.lproj/LaunchScreen.storyboard27
-rw-r--r--tests/projects/objc/metal_app/Application/iOS/Base.lproj/Main.storyboard30
-rw-r--r--tests/projects/objc/metal_app/Application/iOS/Info.plist48
-rw-r--r--tests/projects/objc/metal_app/Application/macOS/Base.lproj/Main.storyboard693
-rw-r--r--tests/projects/objc/metal_app/Application/macOS/Info.plist30
-rw-r--r--tests/projects/objc/metal_app/Application/main.m36
-rw-r--r--tests/projects/objc/metal_app/Application/tvOS/Base.lproj/Main.storyboard30
-rw-r--r--tests/projects/objc/metal_app/Application/tvOS/Info.plist32
-rw-r--r--tests/projects/objc/metal_app/Configuration/SampleCode.xcconfig13
-rw-r--r--tests/projects/objc/metal_app/HelloTriangle.xcodeproj/.xcodesamplecode.plist5
-rw-r--r--tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.pbxproj681
-rw-r--r--tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings8
-rw-r--r--tests/projects/objc/metal_app/LICENSE/LICENSE.txt8
-rw-r--r--tests/projects/objc/metal_app/README.md332
-rw-r--r--tests/projects/objc/metal_app/Renderer/AAPLRenderer.h14
-rw-r--r--tests/projects/objc/metal_app/Renderer/AAPLRenderer.m132
-rw-r--r--tests/projects/objc/metal_app/Renderer/AAPLShaderTypes.h31
-rw-r--r--tests/projects/objc/metal_app/Renderer/AAPLShaders.metal62
-rw-r--r--tests/projects/objc/metal_app/xmake.lua22
-rw-r--r--tests/projects/openmp/hello/xmake.lua5
-rw-r--r--tests/projects/openmp/loop/xmake.lua5
-rw-r--r--tests/projects/other/bin2c/xmake.lua4
-rw-r--r--tests/projects/other/build_deps/xmake.lua16
-rw-r--r--tests/projects/other/glsl2spv/.gitignore8
-rw-r--r--tests/projects/other/glsl2spv/src/main.c16
-rw-r--r--tests/projects/other/glsl2spv/src/test.frag6
-rw-r--r--tests/projects/other/glsl2spv/src/test.vert5
-rw-r--r--tests/projects/other/glsl2spv/xmake.lua11
-rw-r--r--tests/projects/other/merge_archive2/src/add.c4
-rw-r--r--tests/projects/other/merge_archive2/src/main.c17
-rw-r--r--tests/projects/other/merge_archive2/src/mul.c4
-rw-r--r--tests/projects/other/merge_archive2/src/sub.c4
-rw-r--r--tests/projects/other/merge_archive2/src/subdir/add.c4
-rw-r--r--tests/projects/other/merge_archive2/src/subdir/sub.c4
-rw-r--r--tests/projects/other/merge_archive2/test.lua6
-rw-r--r--tests/projects/other/merge_archive2/xmake.lua21
-rw-r--r--tests/projects/other/multiplats_vs/xmake.lua2
-rw-r--r--tests/projects/package/brew/.gitignore8
-rw-r--r--tests/projects/package/brew/src/main.cpp9
-rw-r--r--tests/projects/package/brew/xmake.lua78
-rw-r--r--tests/projects/package/cmake/.gitignore8
-rw-r--r--tests/projects/package/cmake/src/main.cpp9
-rw-r--r--tests/projects/package/cmake/xmake.lua12
-rw-r--r--tests/projects/package/conan/.gitignore8
-rw-r--r--tests/projects/package/conan/src/main.cpp9
-rw-r--r--tests/projects/package/conan/xmake.lua9
-rw-r--r--tests/projects/package/multiconfig/xmake-requires.lock31
-rw-r--r--tests/projects/package/multiconfig/xmake.lua1
-rw-r--r--tests/projects/package/toolchain_muslcc/xmake-requires.lock145
-rw-r--r--tests/projects/package/toolchain_muslcc/xmake.lua3
-rw-r--r--tests/projects/package/vcpkg/.gitignore8
-rw-r--r--tests/projects/package/vcpkg/src/main.cpp9
-rw-r--r--tests/projects/package/vcpkg/xmake.lua8
-rw-r--r--tests/projects/package/vcpkg_manifest/.gitignore8
-rw-r--r--tests/projects/package/vcpkg_manifest/src/main.cpp9
-rw-r--r--tests/projects/package/vcpkg_manifest/xmake.lua9
-rw-r--r--tests/projects/pascal/console/src/main.pas4
-rw-r--r--tests/projects/pascal/console/xmake.lua5
-rw-r--r--tests/projects/pascal/console_with_c/src/foo.c7
-rw-r--r--tests/projects/pascal/console_with_c/src/main.pas12
-rw-r--r--tests/projects/pascal/console_with_c/xmake.lua9
-rw-r--r--tests/projects/pascal/shared/src/foo.pas19
-rw-r--r--tests/projects/pascal/shared/src/main.pas13
-rw-r--r--tests/projects/pascal/shared/xmake.lua9
-rw-r--r--tests/projects/pybind/example/src/example.cpp38
-rw-r--r--tests/projects/pybind/example/xmake.lua8
-rw-r--r--tests/projects/pybind/example_with_soabi/src/example.cpp38
-rw-r--r--tests/projects/pybind/example_with_soabi/xmake.lua8
-rw-r--r--tests/projects/rust/cargo_deps/src/main.rs12
-rw-r--r--tests/projects/rust/cargo_deps/xmake.lua8
-rw-r--r--tests/projects/rust/console/src/main.rs3
-rw-r--r--tests/projects/rust/console/xmake.lua2
-rw-r--r--tests/projects/rust/cxx_call_rust_library/src/bridge.rsx6
-rw-r--r--tests/projects/rust/cxx_call_rust_library/src/foo.rs12
-rw-r--r--tests/projects/rust/cxx_call_rust_library/src/main.cc7
-rw-r--r--tests/projects/rust/cxx_call_rust_library/xmake.lua16
-rw-r--r--tests/projects/rust/rust_call_cxx_library/src/foo.cc3
-rw-r--r--tests/projects/rust/rust_call_cxx_library/src/main.rs9
-rw-r--r--tests/projects/rust/rust_call_cxx_library/test.lua10
-rw-r--r--tests/projects/rust/rust_call_cxx_library/xmake.lua12
-rw-r--r--tests/projects/rust/shared_library/src/foo.rs4
-rw-r--r--tests/projects/rust/shared_library/src/main.rs6
-rw-r--r--tests/projects/rust/shared_library/xmake.lua12
-rw-r--r--tests/projects/rust/static_library/src/foo.rs4
-rw-r--r--tests/projects/rust/static_library/src/interfaces.rs5
-rw-r--r--tests/projects/rust/static_library/src/main.rs8
-rw-r--r--tests/projects/rust/static_library/xmake.lua6
-rw-r--r--tests/projects/swig/lua_c/src/example.c4
-rw-r--r--tests/projects/swig/lua_c/src/example.i5
-rw-r--r--tests/projects/swig/lua_c/xmake.lua8
-rw-r--r--tests/projects/swig/python_c/src/example.c14
-rw-r--r--tests/projects/swig/python_c/src/example.i11
-rw-r--r--tests/projects/swig/python_c/xmake.lua8
-rw-r--r--tests/projects/swig/python_c_with_soabi/src/example.c14
-rw-r--r--tests/projects/swig/python_c_with_soabi/src/example.i11
-rw-r--r--tests/projects/swig/python_c_with_soabi/xmake.lua8
-rw-r--r--tests/projects/swig/python_cpp/src/example.cpp14
-rw-r--r--tests/projects/swig/python_cpp/src/example.i11
-rw-r--r--tests/projects/swig/python_cpp/xmake.lua8
-rw-r--r--tests/projects/vala/gtk+3/src/main.vala24
-rw-r--r--tests/projects/vala/gtk+3/xmake.lua10
-rw-r--r--tests/projects/vala/sharedlib/src/main.vala6
-rw-r--r--tests/projects/vala/sharedlib/src/mymath.vala9
-rw-r--r--tests/projects/vala/sharedlib/xmake.lua18
-rw-r--r--tests/projects/vala/sqlite3/src/main.vala63
-rw-r--r--tests/projects/vala/sqlite3/xmake.lua10
-rw-r--r--tests/projects/vala/staticlib/src/main.vala6
-rw-r--r--tests/projects/vala/staticlib/src/mymath.vala9
-rw-r--r--tests/projects/vala/staticlib/xmake.lua18
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.c (renamed from tests/projects/wdk/kmdf/ioctl/driver/nonpnp.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.h (renamed from tests/projects/wdk/kmdf/ioctl/driver/nonpnp.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.rc (renamed from tests/projects/wdk/kmdf/ioctl/driver/nonpnp.rc)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/driver/trace.h (renamed from tests/projects/wdk/kmdf/ioctl/driver/trace.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/exe/install.c (renamed from tests/projects/wdk/kmdf/ioctl/exe/install.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/exe/nonpnp.inf (renamed from tests/projects/wdk/kmdf/ioctl/exe/nonpnp.inf)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c (renamed from tests/projects/wdk/kmdf/ioctl/exe/testapp.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/localwpp.ini (renamed from tests/projects/wdk/kmdf/ioctl/localwpp.ini)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/public.h (renamed from tests/projects/wdk/kmdf/ioctl/public.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/xmake.lua (renamed from tests/projects/wdk/kmdf/ioctl/xmake.lua)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/error.c (renamed from tests/projects/wdk/kmdf/serial/error.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/flush.c (renamed from tests/projects/wdk/kmdf/serial/flush.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/immediat.c (renamed from tests/projects/wdk/kmdf/serial/immediat.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/initunlo.c (renamed from tests/projects/wdk/kmdf/serial/initunlo.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/ioctl.c (renamed from tests/projects/wdk/kmdf/serial/ioctl.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/isr.c (renamed from tests/projects/wdk/kmdf/serial/isr.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/log.c (renamed from tests/projects/wdk/kmdf/serial/log.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/log.h (renamed from tests/projects/wdk/kmdf/serial/log.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/modmflow.c (renamed from tests/projects/wdk/kmdf/serial/modmflow.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/openclos.c (renamed from tests/projects/wdk/kmdf/serial/openclos.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/pnp.c (renamed from tests/projects/wdk/kmdf/serial/pnp.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/power.c (renamed from tests/projects/wdk/kmdf/serial/power.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/precomp.h (renamed from tests/projects/wdk/kmdf/serial/precomp.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/precompsrc.c (renamed from tests/projects/wdk/kmdf/serial/precompsrc.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/purge.c (renamed from tests/projects/wdk/kmdf/serial/purge.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/qsfile.c (renamed from tests/projects/wdk/kmdf/serial/qsfile.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/read.c (renamed from tests/projects/wdk/kmdf/serial/read.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/registry.c (renamed from tests/projects/wdk/kmdf/serial/registry.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/serial.h (renamed from tests/projects/wdk/kmdf/serial/serial.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/serial.inx (renamed from tests/projects/wdk/kmdf/serial/serial.inx)bin6212 -> 6212 bytes
-rw-r--r--tests/projects/windows/driver/kmdf/serial/serial.rc (renamed from tests/projects/wdk/kmdf/serial/serial.rc)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/serialp.h (renamed from tests/projects/wdk/kmdf/serial/serialp.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/serlog.mc (renamed from tests/projects/wdk/kmdf/serial/serlog.mc)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/trace.h (renamed from tests/projects/wdk/kmdf/serial/trace.h)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/utils.c (renamed from tests/projects/wdk/kmdf/serial/utils.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/waitmask.c (renamed from tests/projects/wdk/kmdf/serial/waitmask.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/wmi.c (renamed from tests/projects/wdk/kmdf/serial/wmi.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/write.c (renamed from tests/projects/wdk/kmdf/serial/write.c)0
-rw-r--r--tests/projects/windows/driver/kmdf/serial/xmake.lua (renamed from tests/projects/wdk/kmdf/serial/xmake.lua)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/device.c (renamed from tests/projects/wdk/umdf/echo/driver/device.c)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/device.h (renamed from tests/projects/wdk/umdf/echo/driver/device.h)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/driver.c (renamed from tests/projects/wdk/umdf/echo/driver/driver.c)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/driver.h (renamed from tests/projects/wdk/umdf/echo/driver/driver.h)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/echoum.inx (renamed from tests/projects/wdk/umdf/echo/driver/echoum.inx)bin3924 -> 3924 bytes
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/queue.c (renamed from tests/projects/wdk/umdf/echo/driver/queue.c)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/driver/queue.h (renamed from tests/projects/wdk/umdf/echo/driver/queue.h)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/exe/echoapp.cpp (renamed from tests/projects/wdk/umdf/echo/exe/echoapp.cpp)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/exe/public.h (renamed from tests/projects/wdk/umdf/echo/exe/public.h)0
-rw-r--r--tests/projects/windows/driver/umdf/echo/xmake.lua (renamed from tests/projects/wdk/umdf/echo/xmake.lua)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/Skeleton.rc (renamed from tests/projects/wdk/umdf/skeleton/Skeleton.rc)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/UMDFSkeleton_OSR.inx (renamed from tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inx)bin5646 -> 5646 bytes
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/UMDFSkeleton_Root.inx (renamed from tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inx)bin3798 -> 3798 bytes
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/comsup.cpp (renamed from tests/projects/wdk/umdf/skeleton/comsup.cpp)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/comsup.h (renamed from tests/projects/wdk/umdf/skeleton/comsup.h)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/device.cpp (renamed from tests/projects/wdk/umdf/skeleton/device.cpp)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/device.h (renamed from tests/projects/wdk/umdf/skeleton/device.h)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/dllsup.cpp (renamed from tests/projects/wdk/umdf/skeleton/dllsup.cpp)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/driver.cpp (renamed from tests/projects/wdk/umdf/skeleton/driver.cpp)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/driver.h (renamed from tests/projects/wdk/umdf/skeleton/driver.h)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/exports.def (renamed from tests/projects/wdk/umdf/skeleton/exports.def)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/internal.h (renamed from tests/projects/wdk/umdf/skeleton/internal.h)0
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/xmake.lua (renamed from tests/projects/wdk/umdf/skeleton/xmake.lua)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/SampleDSM.inf (renamed from tests/projects/wdk/wdm/msdsm/SampleDSM.inf)bin5354 -> 5354 bytes
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/dsmmain.c (renamed from tests/projects/wdk/wdm/msdsm/dsmmain.c)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/dsmtrace.mof (renamed from tests/projects/wdk/wdm/msdsm/dsmtrace.mof)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/intrface.c (renamed from tests/projects/wdk/wdm/msdsm/intrface.c)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/msdsm.h (renamed from tests/projects/wdk/wdm/msdsm/msdsm.h)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/msdsm.mof (renamed from tests/projects/wdk/wdm/msdsm/msdsm.mof)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/msdsm.rc (renamed from tests/projects/wdk/wdm/msdsm/msdsm.rc)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/msdsmdsm.mof (renamed from tests/projects/wdk/wdm/msdsm/msdsmdsm.mof)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/precomp.h (renamed from tests/projects/wdk/wdm/msdsm/precomp.h)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/precompsrc.c (renamed from tests/projects/wdk/wdm/msdsm/precompsrc.c)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/prototypes.h (renamed from tests/projects/wdk/wdm/msdsm/prototypes.h)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/trace.h (renamed from tests/projects/wdk/wdm/msdsm/trace.h)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/utils.c (renamed from tests/projects/wdk/wdm/msdsm/utils.c)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/wmi.c (renamed from tests/projects/wdk/wdm/msdsm/wmi.c)0
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/xmake.lua (renamed from tests/projects/wdk/wdm/msdsm/xmake.lua)0
-rw-r--r--tests/projects/windows/driver/wdm/perfcounters/kcs.c (renamed from tests/projects/wdk/wdm/perfcounters/kcs.c)0
-rw-r--r--tests/projects/windows/driver/wdm/perfcounters/kcs.h (renamed from tests/projects/wdk/wdm/perfcounters/kcs.h)0
-rw-r--r--tests/projects/windows/driver/wdm/perfcounters/kcs.man (renamed from tests/projects/wdk/wdm/perfcounters/kcs.man)0
-rw-r--r--tests/projects/windows/driver/wdm/perfcounters/kcs.rc (renamed from tests/projects/wdk/wdm/perfcounters/kcs.rc)0
-rw-r--r--tests/projects/windows/driver/wdm/perfcounters/xmake.lua (renamed from tests/projects/wdk/wdm/perfcounters/xmake.lua)0
-rw-r--r--tests/projects/windows/winsdk/usbview/app.config (renamed from tests/projects/winsdk/usbview/app.config)0
-rw-r--r--tests/projects/windows/winsdk/usbview/bang.ico (renamed from tests/projects/winsdk/usbview/bang.ico)bin1846 -> 1846 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/codeanalysis.h (renamed from tests/projects/winsdk/usbview/codeanalysis.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/debug.c (renamed from tests/projects/winsdk/usbview/debug.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/devnode.c (renamed from tests/projects/winsdk/usbview/devnode.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/dispaud.c (renamed from tests/projects/winsdk/usbview/dispaud.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/display.c (renamed from tests/projects/winsdk/usbview/display.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/dispvid.c (renamed from tests/projects/winsdk/usbview/dispvid.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/enum.c (renamed from tests/projects/winsdk/usbview/enum.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/h264.c (renamed from tests/projects/winsdk/usbview/h264.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/h264.h (renamed from tests/projects/winsdk/usbview/h264.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/hub.ico (renamed from tests/projects/winsdk/usbview/hub.ico)bin766 -> 766 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/langidlist.h (renamed from tests/projects/winsdk/usbview/langidlist.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/monitor.ico (renamed from tests/projects/winsdk/usbview/monitor.ico)bin10134 -> 10134 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/port.ico (renamed from tests/projects/winsdk/usbview/port.ico)bin766 -> 766 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/resource.h (renamed from tests/projects/winsdk/usbview/resource.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/split.cur (renamed from tests/projects/winsdk/usbview/split.cur)bin326 -> 326 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/ssport.ico (renamed from tests/projects/winsdk/usbview/ssport.ico)bin766 -> 766 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/ssusb.ico (renamed from tests/projects/winsdk/usbview/ssusb.ico)bin766 -> 766 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/usb.ico (renamed from tests/projects/winsdk/usbview/usb.ico)bin766 -> 766 bytes
-rw-r--r--tests/projects/windows/winsdk/usbview/usbdesc.h (renamed from tests/projects/winsdk/usbview/usbdesc.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/usbschema.hpp (renamed from tests/projects/winsdk/usbview/usbschema.hpp)0
-rw-r--r--tests/projects/windows/winsdk/usbview/usbviddesc.h (renamed from tests/projects/winsdk/usbview/usbviddesc.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/uvcdesc.h (renamed from tests/projects/winsdk/usbview/uvcdesc.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/uvcview.c (renamed from tests/projects/winsdk/usbview/uvcview.c)0
-rw-r--r--tests/projects/windows/winsdk/usbview/uvcview.h (renamed from tests/projects/winsdk/usbview/uvcview.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/uvcview.rc (renamed from tests/projects/winsdk/usbview/uvcview.rc)0
-rw-r--r--tests/projects/windows/winsdk/usbview/vndrlist.h (renamed from tests/projects/winsdk/usbview/vndrlist.h)0
-rw-r--r--tests/projects/windows/winsdk/usbview/xmake.lua (renamed from tests/projects/winsdk/usbview/xmake.lua)0
-rw-r--r--tests/projects/windows/winsdk/usbview/xmlhelper.cpp (renamed from tests/projects/winsdk/usbview/xmlhelper.cpp)0
-rw-r--r--tests/projects/windows/winsdk/usbview/xmlhelper.h (renamed from tests/projects/winsdk/usbview/xmlhelper.h)0
-rw-r--r--tests/projects/windows/winsdk/windemo/main.cpp (renamed from tests/projects/winsdk/windemo/main.cpp)0
-rw-r--r--tests/projects/windows/winsdk/windemo/resource.h (renamed from tests/projects/winsdk/windemo/resource.h)0
-rw-r--r--tests/projects/windows/winsdk/windemo/small.ico (renamed from tests/projects/winsdk/windemo/small.ico)bin23558 -> 23558 bytes
-rw-r--r--tests/projects/windows/winsdk/windemo/stdafx.cpp (renamed from tests/projects/winsdk/windemo/stdafx.cpp)0
-rw-r--r--tests/projects/windows/winsdk/windemo/stdafx.h (renamed from tests/projects/winsdk/windemo/stdafx.h)0
-rw-r--r--tests/projects/windows/winsdk/windemo/targetver.h (renamed from tests/projects/winsdk/windemo/targetver.h)0
-rw-r--r--tests/projects/windows/winsdk/windemo/test (renamed from tests/projects/winsdk/windemo/test)0
-rw-r--r--tests/projects/windows/winsdk/windemo/test.h (renamed from tests/projects/winsdk/windemo/test.h)0
-rw-r--r--tests/projects/windows/winsdk/windemo/test.ico (renamed from tests/projects/winsdk/windemo/test.ico)bin23558 -> 23558 bytes
-rw-r--r--tests/projects/windows/winsdk/windemo/test.rc (renamed from tests/projects/winsdk/windemo/test.rc)0
-rw-r--r--tests/projects/windows/winsdk/windemo/xmake.lua (renamed from tests/projects/winsdk/windemo/xmake.lua)0
-rw-r--r--tests/projects/xmake_cli/xmake/src/xmake.rc2
-rw-r--r--tests/run.lua10
-rw-r--r--xmake/actions/build/build.lua40
-rw-r--r--xmake/actions/build/build_files.lua9
-rw-r--r--xmake/actions/build/kinds/binary.lua22
-rw-r--r--xmake/actions/build/kinds/shared.lua22
-rw-r--r--xmake/actions/build/kinds/static.lua22
-rw-r--r--xmake/actions/build/main.lua31
-rw-r--r--xmake/actions/build/xmake.lua7
-rw-r--r--xmake/actions/clean/main.lua2
-rw-r--r--xmake/actions/config/configfiles.lua28
-rw-r--r--xmake/actions/config/main.lua3
-rw-r--r--xmake/actions/config/menuconf.lua2
-rw-r--r--xmake/actions/create/main.lua4
-rw-r--r--xmake/actions/create/xmake.lua3
-rw-r--r--xmake/actions/global/menuconf.lua1
-rw-r--r--xmake/actions/global/xmake.lua108
-rw-r--r--xmake/actions/install/install_admin.lua5
-rw-r--r--xmake/actions/install/main.lua4
-rw-r--r--xmake/actions/package/local/main.lua78
-rw-r--r--xmake/actions/package/oldpkg/main.lua25
-rw-r--r--xmake/actions/package/remote/main.lua28
-rw-r--r--xmake/actions/require/main.lua2
-rw-r--r--xmake/actions/require/xmake.lua3
-rw-r--r--xmake/actions/run/main.lua38
-rw-r--r--xmake/actions/run/xmake.lua13
-rw-r--r--xmake/actions/uninstall/main.lua2
-rw-r--r--xmake/actions/uninstall/uninstall_admin.lua5
-rw-r--r--xmake/actions/update/main.lua15
-rw-r--r--xmake/core/_xmake_main.lua12
-rw-r--r--xmake/core/base/bit.lua21
-rw-r--r--xmake/core/base/bytes.lua55
-rw-r--r--xmake/core/base/colors.lua6
-rw-r--r--xmake/core/base/compat/bit.lua73
-rw-r--r--xmake/core/base/compat/env.lua98
-rw-r--r--xmake/core/base/deprecated/interpreter.lua140
-rw-r--r--xmake/core/base/dump.lua2
-rw-r--r--xmake/core/base/filter.lua22
-rw-r--r--xmake/core/base/interpreter.lua305
-rw-r--r--xmake/core/base/json.lua2
-rw-r--r--xmake/core/base/libc.lua134
-rw-r--r--xmake/core/base/os.lua47
-rw-r--r--xmake/core/base/pipe.lua2
-rw-r--r--xmake/core/base/scheduler.lua16
-rw-r--r--xmake/core/base/scopeinfo.lua144
-rw-r--r--xmake/core/base/serialize.lua19
-rw-r--r--xmake/core/base/socket.lua4
-rw-r--r--xmake/core/base/string.lua2
-rw-r--r--xmake/core/base/table.lua262
-rw-r--r--xmake/core/base/tty.lua20
-rw-r--r--xmake/core/base/xmake.lua12
-rw-r--r--xmake/core/main.lua5
-rw-r--r--xmake/core/package/package.lua232
-rw-r--r--xmake/core/package/repository.lua10
-rw-r--r--xmake/core/project/config.lua21
-rw-r--r--xmake/core/project/deprecated/project.lua1
-rw-r--r--xmake/core/project/option.lua165
-rw-r--r--xmake/core/project/policy.lua6
-rw-r--r--xmake/core/project/project.lua114
-rw-r--r--xmake/core/project/rule.lua3
-rw-r--r--xmake/core/project/target.lua369
-rw-r--r--xmake/core/sandbox/modules/debug.lua13
-rw-r--r--xmake/core/sandbox/modules/import/core/base/bit.lua24
-rw-r--r--xmake/core/sandbox/modules/import/core/base/libc.lua24
-rw-r--r--xmake/core/sandbox/modules/import/core/base/semver.lua2
-rw-r--r--xmake/core/sandbox/modules/import/core/package/package.lua20
-rw-r--r--xmake/core/sandbox/modules/import/core/package/repository.lua76
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua87
-rw-r--r--xmake/core/sandbox/modules/import/core/project/target.lua8
-rw-r--r--xmake/core/sandbox/modules/import/core/sandbox/module.lua23
-rw-r--r--xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua1
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_library.lua26
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_program.lua4
-rw-r--r--xmake/core/sandbox/modules/interpreter/os.lua43
-rw-r--r--xmake/core/sandbox/modules/interpreter/print.lua5
-rw-r--r--xmake/core/sandbox/modules/interpreter/unpack.lua4
-rw-r--r--xmake/core/sandbox/modules/interpreter/xmake.lua1
-rw-r--r--xmake/core/sandbox/modules/irpairs.lua2
-rw-r--r--xmake/core/sandbox/modules/os.lua1
-rw-r--r--xmake/core/sandbox/modules/unpack.lua4
-rw-r--r--xmake/core/sandbox/modules/utils.lua8
-rw-r--r--xmake/core/sandbox/modules/winos.lua9
-rw-r--r--xmake/core/sandbox/modules/xmake.lua2
-rw-r--r--xmake/core/tool/builder.lua12
-rw-r--r--xmake/core/tool/compiler.lua37
-rw-r--r--xmake/core/tool/tool.lua4
-rw-r--r--xmake/core/tool/toolchain.lua10
-rw-r--r--xmake/core/ui/label.lua2
-rw-r--r--xmake/core/ui/program.lua9
-rw-r--r--xmake/core/ui/textedit.lua2
-rw-r--r--xmake/includes/check_cflags.lua24
-rw-r--r--xmake/includes/check_cfuncs.lua20
-rw-r--r--xmake/includes/check_cincludes.lua23
-rw-r--r--xmake/includes/check_csnippets.lua50
-rw-r--r--xmake/includes/check_ctypes.lua18
-rw-r--r--xmake/includes/check_cxxflags.lua24
-rw-r--r--xmake/includes/check_cxxfuncs.lua18
-rw-r--r--xmake/includes/check_cxxincludes.lua17
-rw-r--r--xmake/includes/check_cxxsnippets.lua50
-rw-r--r--xmake/includes/check_cxxtypes.lua18
-rw-r--r--xmake/includes/check_features.lua17
-rw-r--r--xmake/includes/check_links.lua17
-rw-r--r--xmake/includes/check_macros.lua132
-rw-r--r--xmake/includes/check_syslinks.lua17
-rw-r--r--xmake/includes/find_and_add_packages.lua2
-rw-r--r--xmake/includes/qt_add_static_plugins.lua4
-rw-r--r--xmake/languages/asm/xmake.lua3
-rw-r--r--xmake/languages/c++/load.lua8
-rw-r--r--xmake/languages/nim/load.lua56
-rw-r--r--xmake/languages/nim/xmake.lua87
-rw-r--r--xmake/languages/pascal/check_main.lua40
-rw-r--r--xmake/languages/pascal/load.lua74
-rw-r--r--xmake/languages/pascal/xmake.lua90
-rw-r--r--xmake/languages/rust/xmake.lua39
-rw-r--r--xmake/modules/cli/amalgamate.lua108
-rw-r--r--xmake/modules/core/project/depend.lua15
-rw-r--r--xmake/modules/core/tools/ar.lua18
-rw-r--r--xmake/modules/core/tools/armar.lua26
-rw-r--r--xmake/modules/core/tools/armasm.lua179
-rw-r--r--xmake/modules/core/tools/armcc.lua183
-rw-r--r--xmake/modules/core/tools/armclang.lua32
-rw-r--r--xmake/modules/core/tools/armlink.lua61
-rw-r--r--xmake/modules/core/tools/circle.lua34
-rw-r--r--xmake/modules/core/tools/cl.lua85
-rw-r--r--xmake/modules/core/tools/clang.lua13
-rw-r--r--xmake/modules/core/tools/clang_cl.lua10
-rw-r--r--xmake/modules/core/tools/dmd.lua8
-rw-r--r--xmake/modules/core/tools/fpc.lua110
-rw-r--r--xmake/modules/core/tools/gcc.lua56
-rw-r--r--xmake/modules/core/tools/go.lua38
-rw-r--r--xmake/modules/core/tools/ml.lua43
-rw-r--r--xmake/modules/core/tools/nim.lua161
-rw-r--r--xmake/modules/core/tools/nvcc.lua32
-rw-r--r--xmake/modules/core/tools/rc.lua2
-rw-r--r--xmake/modules/core/tools/rustc.lua82
-rw-r--r--xmake/modules/core/tools/sdcc.lua33
-rw-r--r--xmake/modules/core/tools/zig.lua9
-rw-r--r--xmake/modules/detect/sdks/find_iccenv.lua21
-rw-r--r--xmake/modules/detect/sdks/find_ifortenv.lua28
-rw-r--r--xmake/modules/detect/sdks/find_mdk.lua123
-rw-r--r--xmake/modules/detect/sdks/find_mingw.lua3
-rw-r--r--xmake/modules/detect/sdks/find_ndk.lua20
-rw-r--r--xmake/modules/detect/sdks/find_qt.lua30
-rw-r--r--xmake/modules/detect/sdks/find_vstudio.lua113
-rw-r--r--xmake/modules/detect/tools/circle/has_flags.lua23
-rw-r--r--xmake/modules/detect/tools/cl/cfeatures.lua5
-rw-r--r--xmake/modules/detect/tools/cl/cxxfeatures.lua10
-rw-r--r--xmake/modules/detect/tools/cl/has_flags.lua8
-rw-r--r--xmake/modules/detect/tools/clang/cfeatures.lua8
-rw-r--r--xmake/modules/detect/tools/clang/cxxfeatures.lua12
-rw-r--r--xmake/modules/detect/tools/clang_cl/has_flags.lua2
-rw-r--r--xmake/modules/detect/tools/dmd/has_flags.lua2
-rw-r--r--xmake/modules/detect/tools/find_7z.lua5
-rw-r--r--xmake/modules/detect/tools/find_armar.lua65
-rw-r--r--xmake/modules/detect/tools/find_armasm.lua65
-rw-r--r--xmake/modules/detect/tools/find_armcc.lua60
-rw-r--r--xmake/modules/detect/tools/find_armclang.lua59
-rw-r--r--xmake/modules/detect/tools/find_armlink.lua65
-rw-r--r--xmake/modules/detect/tools/find_cargo.lua52
-rw-r--r--xmake/modules/detect/tools/find_circle.lua52
-rw-r--r--xmake/modules/detect/tools/find_cxxbridge.lua52
-rw-r--r--xmake/modules/detect/tools/find_fpc.lua52
-rw-r--r--xmake/modules/detect/tools/find_glslangValidator.lua52
-rw-r--r--xmake/modules/detect/tools/find_glslc.lua61
-rw-r--r--xmake/modules/detect/tools/find_ifort.lua1
-rw-r--r--xmake/modules/detect/tools/find_llvm_as.lua57
-rw-r--r--xmake/modules/detect/tools/find_make.lua53
-rw-r--r--xmake/modules/detect/tools/find_metal.lua50
-rw-r--r--xmake/modules/detect/tools/find_metallib.lua50
-rw-r--r--xmake/modules/detect/tools/find_nim.lua52
-rw-r--r--xmake/modules/detect/tools/find_nimble.lua52
-rw-r--r--xmake/modules/detect/tools/find_pkg_config.lua2
-rw-r--r--xmake/modules/detect/tools/find_pkgconf.lua52
-rw-r--r--xmake/modules/detect/tools/find_swig.lua53
-rw-r--r--xmake/modules/detect/tools/fpc/has_flags.lua98
-rw-r--r--xmake/modules/detect/tools/gcc/cfeatures.lua7
-rw-r--r--xmake/modules/detect/tools/gcc/cxxfeatures.lua65
-rw-r--r--xmake/modules/detect/tools/gcc/has_flags.lua39
-rw-r--r--xmake/modules/detect/tools/go/has_flags.lua2
-rw-r--r--xmake/modules/detect/tools/ml/has_flags.lua11
-rw-r--r--xmake/modules/detect/tools/nim/has_flags.lua98
-rw-r--r--xmake/modules/detect/tools/rc/has_flags.lua68
-rw-r--r--xmake/modules/detect/tools/rustc/has_flags.lua30
-rw-r--r--xmake/modules/detect/tools/sdcc/has_flags.lua2
-rw-r--r--xmake/modules/detect/tools/swiftc/has_flags.lua2
-rw-r--r--xmake/modules/detect/tools/zig/has_flags.lua2
-rw-r--r--xmake/modules/devel/git/apply.lua13
-rw-r--r--xmake/modules/devel/git/checkout.lua13
-rw-r--r--xmake/modules/devel/git/clean.lua13
-rw-r--r--xmake/modules/devel/git/lastcommit.lua66
-rw-r--r--xmake/modules/devel/git/pull.lua15
-rw-r--r--xmake/modules/devel/git/reset.lua13
-rw-r--r--xmake/modules/devel/git/submodule/update.lua21
-rw-r--r--xmake/modules/lib/detect/check_cxsnippets.lua59
-rw-r--r--xmake/modules/lib/detect/features.lua5
-rw-r--r--xmake/modules/lib/detect/find_package.lua29
-rw-r--r--xmake/modules/lib/detect/pkgconfig.lua20
-rw-r--r--xmake/modules/net/ping.lua2
-rw-r--r--xmake/modules/package/manager/apt/find_package.lua72
-rw-r--r--xmake/modules/package/manager/brew/find_package.lua10
-rw-r--r--xmake/modules/package/manager/cargo/configurations.lua28
-rw-r--r--xmake/modules/package/manager/cargo/find_package.lua58
-rw-r--r--xmake/modules/package/manager/cargo/install_package.lua95
-rw-r--r--xmake/modules/package/manager/clib/configurations.lua30
-rw-r--r--xmake/modules/package/manager/clib/install_package.lua21
-rw-r--r--xmake/modules/package/manager/cmake/configurations.lua31
-rw-r--r--xmake/modules/package/manager/cmake/find_package.lua282
-rw-r--r--xmake/modules/package/manager/conan/configurations.lua33
-rw-r--r--xmake/modules/package/manager/conan/find_package.lua2
-rw-r--r--xmake/modules/package/manager/conan/install_package.lua44
-rw-r--r--xmake/modules/package/manager/conda/find_package.lua4
-rw-r--r--xmake/modules/package/manager/dub/find_package.lua4
-rw-r--r--xmake/modules/package/manager/dub/install_package.lua2
-rw-r--r--xmake/modules/package/manager/find_package.lua4
-rw-r--r--xmake/modules/package/manager/install_package.lua4
-rw-r--r--xmake/modules/package/manager/nimble/find_package.lua67
-rw-r--r--xmake/modules/package/manager/nimble/install_package.lua58
-rw-r--r--xmake/modules/package/manager/pacman/find_package.lua124
-rw-r--r--xmake/modules/package/manager/pkgconfig/find_package.lua1
-rw-r--r--xmake/modules/package/manager/system/find_package.lua97
-rw-r--r--xmake/modules/package/manager/vcpkg/configurations.lua48
-rw-r--r--xmake/modules/package/manager/vcpkg/find_package.lua130
-rw-r--r--xmake/modules/package/manager/vcpkg/install_package.lua151
-rw-r--r--xmake/modules/package/manager/xmake/find_package.lua54
-rw-r--r--xmake/modules/package/manager/xmake/search_package.lua5
-rw-r--r--xmake/modules/package/tools/autoconf.lua136
-rw-r--r--xmake/modules/package/tools/cmake.lua61
-rw-r--r--xmake/modules/package/tools/make.lua61
-rw-r--r--xmake/modules/package/tools/meson.lua107
-rw-r--r--xmake/modules/package/tools/ninja.lua11
-rw-r--r--xmake/modules/package/tools/scons.lua2
-rw-r--r--xmake/modules/package/tools/xmake.lua19
-rw-r--r--xmake/modules/private/action/build/object.lua8
-rw-r--r--xmake/modules/private/action/require/impl/actions/download.lua35
-rw-r--r--xmake/modules/private/action/require/impl/actions/download_resources.lua6
-rw-r--r--xmake/modules/private/action/require/impl/actions/install.lua58
-rw-r--r--xmake/modules/private/action/require/impl/actions/patch_sources.lua3
-rw-r--r--xmake/modules/private/action/require/impl/install_packages.lua38
-rw-r--r--xmake/modules/private/action/require/impl/lock_packages.lua72
-rw-r--r--xmake/modules/private/action/require/impl/package.lua178
-rw-r--r--xmake/modules/private/action/require/impl/packagenv.lua2
-rw-r--r--xmake/modules/private/action/require/impl/register_packages.lua13
-rw-r--r--xmake/modules/private/action/require/impl/remove_packages.lua2
-rw-r--r--xmake/modules/private/action/require/impl/repository.lua142
-rw-r--r--xmake/modules/private/action/require/impl/search_packages.lua2
-rw-r--r--xmake/modules/private/action/require/impl/utils/requirekey.lua60
-rw-r--r--xmake/modules/private/action/require/install.lua2
-rw-r--r--xmake/modules/private/action/trybuild/autotools.lua3
-rw-r--r--xmake/modules/private/action/trybuild/cmake.lua3
-rw-r--r--xmake/modules/private/action/trybuild/meson.lua3
-rw-r--r--xmake/modules/private/async/jobpool.lua15
-rw-r--r--xmake/modules/private/async/runjobs.lua4
-rw-r--r--xmake/modules/private/tools/gcc/parse_deps.lua18
-rw-r--r--xmake/modules/private/utils/batchcmds.lua22
-rw-r--r--xmake/modules/private/utils/bin2c.lua11
-rw-r--r--xmake/modules/private/xrepo/action/env.lua177
-rw-r--r--xmake/modules/private/xrepo/action/export.lua2
-rw-r--r--xmake/modules/private/xrepo/action/fetch.lua2
-rw-r--r--xmake/modules/private/xrepo/action/import.lua2
-rw-r--r--xmake/modules/private/xrepo/action/info.lua2
-rw-r--r--xmake/modules/private/xrepo/action/install.lua4
-rw-r--r--xmake/modules/private/xrepo/action/remove.lua2
-rw-r--r--xmake/modules/target/action/install/cmake_importfiles.lua101
-rw-r--r--xmake/modules/target/action/install/main.lua11
-rw-r--r--xmake/modules/target/action/install/pkgconfig_importfiles.lua25
-rw-r--r--xmake/modules/target/action/install/unix.lua95
-rw-r--r--xmake/modules/target/action/install/windows.lua28
-rw-r--r--xmake/modules/target/action/uninstall/unix.lua72
-rw-r--r--xmake/modules/target/action/uninstall/windows.lua11
-rw-r--r--xmake/modules/utils/archive/extension.lua3
-rw-r--r--xmake/modules/utils/archive/extract.lua77
-rw-r--r--xmake/modules/utils/archive/merge_staticlib.lua73
-rw-r--r--xmake/modules/utils/progress.lua (renamed from xmake/modules/private/utils/progress.lua)2
-rw-r--r--xmake/platforms/linux/xmake.lua2
-rw-r--r--xmake/platforms/macosx/xmake.lua2
-rw-r--r--xmake/platforms/mingw/xmake.lua4
-rw-r--r--xmake/platforms/windows/xmake.lua2
-rw-r--r--xmake/plugins/lua/main.lua2
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua29
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua245
-rw-r--r--xmake/plugins/project/make/makefile.lua10
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua238
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua345
-rw-r--r--xmake/plugins/project/vstudio/impl/vsfile.lua2
-rw-r--r--xmake/plugins/project/vstudio/impl/vsinfo.lua2
-rw-r--r--xmake/plugins/project/vsxmake/render.lua4
-rw-r--r--xmake/plugins/project/vsxmake/vsproj/Xmake.props2
-rw-r--r--xmake/plugins/project/vsxmake/vsproj/Xmake.targets2
-rw-r--r--xmake/plugins/project/vsxmake/vsxmake.lua21
-rw-r--r--xmake/plugins/repo/main.lua7
-rw-r--r--xmake/plugins/show/info/target.lua8
-rw-r--r--xmake/plugins/show/lists/architectures.lua51
-rw-r--r--xmake/plugins/show/showlist.lua2
-rw-r--r--xmake/rules/c++/modules/build_modulefiles.lua151
-rw-r--r--xmake/rules/c++/modules/build_modules/clang.lua139
-rw-r--r--xmake/rules/c++/modules/build_modules/gcc.lua96
-rw-r--r--xmake/rules/c++/modules/build_modules/module_parser.lua118
-rw-r--r--xmake/rules/c++/modules/build_modules/msvc.lua181
-rw-r--r--xmake/rules/c++/modules/xmake.lua40
-rw-r--r--xmake/rules/c++/openmp/load.lua1
-rw-r--r--xmake/rules/c++/openmp/xmake.lua4
-rw-r--r--xmake/rules/c++/unity_build/unity_build.lua139
-rw-r--r--xmake/rules/c++/unity_build/xmake.lua63
-rw-r--r--xmake/rules/cuda/devlink/xmake.lua2
-rw-r--r--xmake/rules/cuda/env/xmake.lua2
-rw-r--r--xmake/rules/cuda/gencodes/xmake.lua44
-rw-r--r--xmake/rules/go/build/object.lua21
-rw-r--r--xmake/rules/go/xmake.lua4
-rw-r--r--xmake/rules/luarocks/module/xmake.lua2
-rw-r--r--xmake/rules/mdk/xmake.lua43
-rw-r--r--xmake/rules/nim/build/target.lua86
-rw-r--r--xmake/rules/nim/xmake.lua37
-rw-r--r--xmake/rules/pascal/build/target.lua88
-rw-r--r--xmake/rules/pascal/xmake.lua33
-rw-r--r--xmake/rules/platform/linux/driver/driver_modules.lua299
-rw-r--r--xmake/rules/platform/linux/driver/xmake.lua33
-rw-r--r--xmake/rules/platform/windows/def/xmake.lua3
-rw-r--r--xmake/rules/platform/windows/manifest/xmake.lua3
-rw-r--r--xmake/rules/plugin/vsxmake/xmake.lua9
-rw-r--r--xmake/rules/python/xmake.lua43
-rw-r--r--xmake/rules/qt/deploy/android.lua36
-rw-r--r--xmake/rules/qt/deploy/macosx.lua2
-rw-r--r--xmake/rules/qt/load.lua10
-rw-r--r--xmake/rules/qt/moc/xmake.lua3
-rw-r--r--xmake/rules/qt/qrc/xmake.lua3
-rw-r--r--xmake/rules/qt/ui/xmake.lua3
-rw-r--r--xmake/rules/qt/xmake.lua22
-rw-r--r--xmake/rules/rust/build/cxxbridge.lua50
-rw-r--r--xmake/rules/rust/build/target.lua26
-rw-r--r--xmake/rules/rust/xmake.lua48
-rw-r--r--xmake/rules/swig/build_module_file.lua55
-rw-r--r--xmake/rules/swig/xmake.lua98
-rw-r--r--xmake/rules/utils/bin2c/xmake.lua11
-rw-r--r--xmake/rules/utils/glsl2spv/xmake.lua90
-rw-r--r--xmake/rules/utils/inherit_links/inherit_links.lua28
-rw-r--r--xmake/rules/utils/install_importfiles/xmake.lua4
-rw-r--r--xmake/rules/utils/merge_archive/merge_archive.lua7
-rw-r--r--xmake/rules/utils/merge_archive/xmake.lua30
-rw-r--r--xmake/rules/utils/merge_object/xmake.lua2
-rw-r--r--xmake/rules/utils/symbols/export_all/export_all.lua5
-rw-r--r--xmake/rules/utils/symbols/export_all/xmake.lua2
-rw-r--r--xmake/rules/utils/symbols/extract/xmake.lua2
-rw-r--r--xmake/rules/vala/xmake.lua112
-rw-r--r--xmake/rules/wdk/env/xmake.lua2
-rw-r--r--xmake/rules/wdk/inf/xmake.lua4
-rw-r--r--xmake/rules/wdk/man/xmake.lua4
-rw-r--r--xmake/rules/wdk/mc/xmake.lua4
-rw-r--r--xmake/rules/wdk/mof/xmake.lua4
-rw-r--r--xmake/rules/wdk/sign/xmake.lua4
-rw-r--r--xmake/rules/wdk/tracewpp/xmake.lua4
-rw-r--r--xmake/rules/winsdk/dotnet/xmake.lua2
-rw-r--r--xmake/rules/winsdk/mfc/env/xmake.lua2
-rw-r--r--xmake/rules/winsdk/xmake.lua2
-rw-r--r--xmake/rules/xcode/application/build.lua2
-rw-r--r--xmake/rules/xcode/application/load.lua11
-rw-r--r--xmake/rules/xcode/application/run.lua4
-rw-r--r--xmake/rules/xcode/application/xmake.lua19
-rw-r--r--xmake/rules/xcode/bundle/xmake.lua4
-rw-r--r--xmake/rules/xcode/framework/xmake.lua4
-rw-r--r--xmake/rules/xcode/info_plist/xmake.lua2
-rw-r--r--xmake/rules/xcode/metal/xmake.lua145
-rw-r--r--xmake/rules/xcode/storyboard/xmake.lua2
-rw-r--r--xmake/rules/xcode/xcassets/xmake.lua2
-rw-r--r--xmake/rules/xmake_cli/xmake.lua2
-rw-r--r--xmake/scripts/cmake_importfiles/xxxTargets.cmake2
-rw-r--r--xmake/scripts/xrepo-hook.psm145
-rw-r--r--xmake/templates/nim/console/project/src/main.nim1
-rw-r--r--xmake/templates/nim/console/project/xmake.lua7
-rw-r--r--xmake/templates/nim/console/template.lua2
-rw-r--r--xmake/templates/nim/shared/project/src/foo.nim6
-rw-r--r--xmake/templates/nim/shared/project/src/main.nim3
-rw-r--r--xmake/templates/nim/shared/project/xmake.lua14
-rw-r--r--xmake/templates/nim/shared/template.lua2
-rw-r--r--xmake/templates/nim/static/project/src/foo.nim6
-rw-r--r--xmake/templates/nim/static/project/src/main.nim3
-rw-r--r--xmake/templates/nim/static/project/xmake.lua14
-rw-r--r--xmake/templates/nim/static/template.lua2
-rw-r--r--xmake/templates/pascal/console/project/src/main.pas4
-rw-r--r--xmake/templates/pascal/console/project/xmake.lua7
-rw-r--r--xmake/templates/pascal/console/template.lua2
-rw-r--r--xmake/templates/pascal/shared/project/src/foo.pas19
-rw-r--r--xmake/templates/pascal/shared/project/src/main.pas13
-rw-r--r--xmake/templates/pascal/shared/project/xmake.lua12
-rw-r--r--xmake/templates/pascal/shared/template.lua2
-rw-r--r--xmake/templates/rust/console/project/src/main.rs3
-rw-r--r--xmake/templates/rust/console/project/xmake.lua8
-rw-r--r--xmake/templates/rust/static/project/src/foo.rs4
-rw-r--r--xmake/templates/rust/static/project/src/interfaces.rs5
-rw-r--r--xmake/templates/rust/static/project/src/main.rs7
-rw-r--r--xmake/templates/rust/static/project/xmake.lua7
-rw-r--r--xmake/templates/vala/console/project/src/main.vala21
-rw-r--r--xmake/templates/vala/console/project/xmake.lua12
-rw-r--r--xmake/templates/vala/console/template.lua2
-rw-r--r--xmake/templates/vala/shared/project/src/main.vala6
-rw-r--r--xmake/templates/vala/shared/project/src/mymath.vala9
-rw-r--r--xmake/templates/vala/shared/project/xmake.lua18
-rw-r--r--xmake/templates/vala/shared/template.lua2
-rw-r--r--xmake/templates/vala/static/project/src/main.vala6
-rw-r--r--xmake/templates/vala/static/project/src/mymath.vala9
-rw-r--r--xmake/templates/vala/static/project/xmake.lua18
-rw-r--r--xmake/templates/vala/static/template.lua2
-rw-r--r--xmake/toolchains/armcc/xmake.lua53
-rw-r--r--xmake/toolchains/armclang/xmake.lua66
-rw-r--r--xmake/toolchains/circle/xmake.lua51
-rw-r--r--xmake/toolchains/clang/xmake.lua9
-rw-r--r--xmake/toolchains/cross/load.lua1
-rw-r--r--xmake/toolchains/cuda/xmake.lua2
-rw-r--r--xmake/toolchains/emcc/xmake.lua1
-rw-r--r--xmake/toolchains/envs/xmake.lua1
-rw-r--r--xmake/toolchains/fpc/xmake.lua42
-rw-r--r--xmake/toolchains/gcc-10/xmake.lua3
-rw-r--r--xmake/toolchains/gcc-11/xmake.lua3
-rw-r--r--xmake/toolchains/gcc-8/xmake.lua3
-rw-r--r--xmake/toolchains/gcc-9/xmake.lua3
-rw-r--r--xmake/toolchains/gcc/xmake.lua30
-rw-r--r--xmake/toolchains/icc/check.lua32
-rw-r--r--xmake/toolchains/icc/load.lua12
-rw-r--r--xmake/toolchains/ifort/check.lua32
-rw-r--r--xmake/toolchains/ifort/load.lua10
-rw-r--r--xmake/toolchains/llvm/xmake.lua1
-rw-r--r--xmake/toolchains/mingw/xmake.lua2
-rw-r--r--xmake/toolchains/msvc/check.lua2
-rw-r--r--xmake/toolchains/msvc/load.lua19
-rw-r--r--xmake/toolchains/ndk/check.lua1
-rw-r--r--xmake/toolchains/ndk/load.lua7
-rw-r--r--xmake/toolchains/nim/xmake.lua41
-rw-r--r--xmake/toolchains/sdcc/xmake.lua3
-rw-r--r--xmake/toolchains/wasi/xmake.lua62
-rw-r--r--xmake/toolchains/xcode/xmake.lua1
868 files changed, 24178 insertions, 3004 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index 884c8c5f3..000000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,125 +0,0 @@
-#version: v2.1.8.{build}
-image:
- - Visual Studio 2013
- - Visual Studio 2017
-
-platform:
- - x86
- - x64
-
-install:
- # prepare tools
- - ps: Push-Location C:/
- - ps: (New-Item ./winenv/bin -ItemType Directory).FullName
- # nsis
- - ps: Invoke-WebRequest "https://github.com/xmake-mirror/nsis/releases/download/v30b3/nsis-3.04.zip" -UseBasicParsing -OutFile ./nsis.zip
- - ps: Invoke-WebRequest "https://github.com/xmake-mirror/nsis/releases/download/v30b3/nsis-3.04-strlen_8192.zip" -UseBasicParsing -OutFile ./nsis-longstr.zip
- - ps: Invoke-WebRequest "https://github.com/xmake-mirror/nsis/releases/download/v30b3/UAC.zip" -UseBasicParsing -OutFile ./nsis-uac.zip
- - ps: Expand-Archive ./nsis.zip -DestinationPath ./nsis
- - ps: Move-Item ./nsis/*/* ./nsis
- - ps: Expand-Archive ./nsis-longstr.zip -DestinationPath ./nsis -Force
- - ps: Expand-Archive ./nsis-uac.zip -DestinationPath ./nsis -Force
- - ps: Move-Item ./nsis/UAC.nsh ./nsis/Include/
- # 7zip
- - ps: Invoke-WebRequest "https://github.com/xmake-mirror/7zip/releases/download/19.00/7z19.00-$($env:platform).zip" -UseBasicParsing -OutFile .\7zip.zip
- - ps: Expand-Archive ./7zip.zip -DestinationPath ./7zip
- - ps: Copy-Item ./7zip/7z.exe ./winenv/bin
- - ps: Copy-Item ./7zip/7z.dll ./winenv/bin
- # curl
- - ps: Invoke-WebRequest "https://github.com/xmake-io/xmake-win$(if ($env:platform -eq 'x64') { '64' } else { '32' })env/raw/master/bin/curl.exe" -UseBasicParsing -OutFile .\curl.exe
- - ps: Invoke-WebRequest "https://raw.githubusercontent.com/xmake-io/xmake-win$(if ($env:platform -eq 'x64') { '64' } else { '32' })env/master/bin/curl-ca-bundle.crt" -UseBasicParsing -OutFile .\curl-ca-bundle.crt
- - ps: Copy-Item ./curl.exe ./winenv/bin
- - ps: Copy-Item ./curl-ca-bundle.crt ./winenv/bin
- #
- - ps: Pop-Location
- # install xmake
- - ps: git submodule -q update --init --recursive
- - ps: ./scripts/get.ps1 -branch master
-
-before_build:
- - ps: (Get-Command xmake).FileVersionInfo.ProductVersion
-
-build_script:
- # self build
- - ps: Push-Location ./core
- - ps: xmake config --arch=$env:platform
- - ps: xmake build
- - ps: Pop-Location
- # use new xmake
- - ps: Set-AppveyorBuildVariable -Name XMAKE_PROGRAM_DIR -Value $(Resolve-Path ./xmake)
- - ps: Copy-Item -Force .\core\build\xmake.exe $(Get-Command xmake).Path
- - ps: (Get-Command xmake).FileVersionInfo.ProductVersion
- # use bitcodes
- #- ps: xmake l -v private.utils.bcsave --rootname='@programdir' -x 'scripts/**|templates/**' xmake
- #- ps: (Get-Command xmake).FileVersionInfo.ProductVersion
-
-after_build:
- # publish exe
- - ps: Push-AppveyorArtifact .\core\build\xmake.exe -FileName xmake.exe -DeploymentName "xmake-executable"
- - ps: (Get-FileHash .\core\build\xmake.exe -Algorithm SHA256).Hash.ToLower() + " *xmake.exe`n" | Out-File ./shafile -Encoding ASCII -NoNewLine
- # compose & publish installer
- - ps: Copy-Item C:\winenv\ . -Recurse
- - ps: $version = (Get-Command xmake).FileVersionInfo
- - ps: C:\nsis\makensis.exe
- /DMAJOR=$($version.ProductMajorPart)
- /DMINOR=$($version.ProductMinorPart)
- /DALTER=$($version.ProductBuildPart)
- /DBUILD=$($($version.ProductVersion -split '\+')[1])
- /D$($env:platform)
- .\scripts\installer.nsi
- - ps: Push-AppveyorArtifact .\scripts\xmake.exe -FileName xmake-installer.exe -DeploymentName "xmake-installer"
- - ps: (Get-FileHash .\scripts\xmake.exe -Algorithm SHA256).Hash.ToLower() + " *xmake-installer.exe`n" | Out-File ./shafile -Encoding ASCII -NoNewLine -Append
- # publish zip archive
- - ps: Copy-Item .\*.md .\xmake
- - ps: Copy-Item C:\winenv\ .\xmake -Recurse
- - ps: Copy-Item .\core\build\xmake.exe .\xmake
- - ps: Copy-Item .\scripts\xrepo.bat .\xmake\xrepo.bat
- - ps: Copy-Item .\scripts\xrepo.ps1 .\xmake\xrepo.ps1
- - ps: |-
- Add-Type -AssemblyName System.Text.Encoding
- Add-Type -AssemblyName System.IO.Compression.FileSystem
-
- class FixedEncoder : System.Text.UTF8Encoding {
- FixedEncoder() : base($true) { }
-
- [byte[]] GetBytes([string] $s)
- {
- $s = $s.Replace("\", "/")
- return ([System.Text.UTF8Encoding]$this).GetBytes($s)
- }
- }
- Copy-Item .\xmake .\archive\xmake -Recurse
-
- [System.IO.Compression.ZipFile]::CreateFromDirectory("$PWD\archive", "$PWD\archive.zip", [System.IO.Compression.CompressionLevel]::Optimal, $false, [FixedEncoder]::new())
- - ps: Push-AppveyorArtifact .\archive.zip -FileName xmake.zip -DeploymentName "xmake-archive"
- - ps: (Get-FileHash .\archive.zip -Algorithm SHA256).Hash.ToLower() + " *xmake.zip`n" | Out-File ./shafile -Encoding ASCII -NoNewLine -Append
- # publish sha file
- - ps: Push-AppveyorArtifact ./shafile -FileName xmake.sha256 -DeploymentName "xmake-shafile"
-
-test_script:
- - ps: xmake --version
- - ps: Push-Location ./tests
- - ps: |-
- $tests = Get-ChildItem test.lua -Recurse | ForEach-Object {
- $testname = "$(Resolve-Path $_.Directory -Relative)"
- $filename = "$(Resolve-Path $_ -Relative)"
- $fullname = "$($_.FullName)"
- Add-AppveyorTest -Name $testname -Framework "xmake-test" -FileName $filename -Outcome None
- return @{ testname = $testname; filename = $filename; fullname = $fullname }
- }
- - ps: $all_success = $true
- - ps: |-
- $tests | ForEach-Object {
- $testname = $_.testname
- $filename = $_.filename
- Update-AppveyorTest -Name $testname -Framework "xmake-test" -FileName $filename -Outcome Running
- $time = Measure-Command {
- xmake lua --verbose --diagnosis runner.lua $_.fullname >stdout_file 2>stderr_file
- $outcome = if ($?) { "Passed" } else { $all_success = $false; "Failed" }
- }
- Get-Content stdout_file | Out-Host
- Get-Content stderr_file | Out-Host
- Update-AppveyorTest -Name $testname -Framework "xmake-test" -FileName $filename -Outcome $outcome -Duration $time.TotalMilliseconds -StdOut (Get-Content -Raw stdout_file) -StdErr (Get-Content -Raw stderr_file)
- }
- - ps: Pop-Location
- - ps: if ($all_success) { Write-Host "All tests passed!" } else { Write-Error "Some tests failed!" }
diff --git a/.github/workflows/archlinux.yml b/.github/workflows/archlinux.yml
index 2a9755fb2..c9fb04cb4 100644
--- a/.github/workflows/archlinux.yml
+++ b/.github/workflows/archlinux.yml
@@ -9,9 +9,12 @@ on:
jobs:
build:
- container: archlinux:latest
+ container: archlinux:base-devel
runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.head_ref }}-Archlinux
+ cancel-in-progress: true
steps:
- name: Prepare build tools
run: |
diff --git a/.github/workflows/debian_mips64.yml b/.github/workflows/debian_mips64.yml
index 0ee576e1a..a2365b2af 100644
--- a/.github/workflows/debian_mips64.yml
+++ b/.github/workflows/debian_mips64.yml
@@ -9,6 +9,10 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+
+ concurrency:
+ group: ${{ github.head_ref }}-DebianMips64
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml
index f25b4b7d2..0105d35ef 100644
--- a/.github/workflows/fedora.yml
+++ b/.github/workflows/fedora.yml
@@ -12,6 +12,9 @@ jobs:
container: fedora:latest
runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.head_ref }}-Fedora
+ cancel-in-progress: true
steps:
- name: Prepare build tools
run: |
diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml
index a23a653e3..38eb93e22 100644
--- a/.github/workflows/freebsd.yml
+++ b/.github/workflows/freebsd.yml
@@ -9,15 +9,18 @@ on:
jobs:
build:
- runs-on: macos-latest
+ runs-on: macos-10.15
+ concurrency:
+ group: ${{ github.head_ref }}-FreeBSD
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Tests
- uses: vmactions/[email protected]
+ uses: vmactions/[email protected]
with:
usesh: true
mem: 4096
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 7c1308060..1851e45ab 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -8,9 +8,10 @@ on:
jobs:
build:
-
runs-on: ubuntu-latest
-
+ concurrency:
+ group: ${{ github.head_ref }}-Linux
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
@@ -35,7 +36,7 @@ jobs:
run: |
sudo apt install -y ruby ruby-dev rubygems build-essential
sudo gem install --no-document fpm
- scripts/makepkg deb
+ scripts/makepkg deb
- uses: actions/upload-artifact@v2
with:
name: xmake-latest.amd64.deb
@@ -61,11 +62,11 @@ jobs:
sudo apt install -y dh-make rng-tools devscripts lintian
echo "$PPA_GPG_PRIKEY_2C0C68C9" > ppa_gpg.key
gpg --import ppa_gpg.key
- scripts/makeppa groovy
- scripts/makeppa focal
- scripts/makeppa bionic
- scripts/makeppa xenial
- scripts/makeppa trusty
- scripts/makeppa precise
+ scripts/makeppa groovy
+ scripts/makeppa focal
+ scripts/makeppa bionic
+ scripts/makeppa xenial
+ scripts/makeppa trusty
+ scripts/makeppa precise
diff --git a/.github/workflows/linux_luajit.yml b/.github/workflows/linux_luajit.yml
new file mode 100644
index 000000000..919c11550
--- /dev/null
+++ b/.github/workflows/linux_luajit.yml
@@ -0,0 +1,36 @@
+name: Linux (Luajit)
+
+on:
+ pull_request:
+ push:
+ release:
+ types: [published]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.head_ref }}-Linux-Luajit
+ cancel-in-progress: true
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: true
+ - uses: dlang-community/setup-dlang@v1
+ with:
+ compiler: dmd-latest
+ - uses: little-core-labs/[email protected]
+ id: tagName
+
+ - name: Installation
+ run: |
+ make RUNTIME=luajit
+ ./scripts/get.sh __local__ __install_only__
+ source ~/.xmake/profile
+ xmake --version
+
+ - name: Tests
+ run: |
+ xmake lua -v -D tests/run.lua
+ xrepo --version
+
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 7358074bc..c814607ec 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -11,6 +11,9 @@ jobs:
runs-on: macos-latest
+ concurrency:
+ group: ${{ github.head_ref }}-macOS
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
diff --git a/.github/workflows/msys2_mingw.yml b/.github/workflows/msys2_mingw.yml
index 3964d5c2f..35965b4dc 100644
--- a/.github/workflows/msys2_mingw.yml
+++ b/.github/workflows/msys2_mingw.yml
@@ -7,6 +7,11 @@ on:
jobs:
build:
runs-on: windows-latest
+
+ concurrency:
+ group: ${{ github.head_ref }}-MSYS2_MINGW-${{ matrix.arch }}
+ cancel-in-progress: true
+
strategy:
fail-fast: false
matrix:
diff --git a/.github/workflows/ubuntu_arm.yml b/.github/workflows/ubuntu_arm.yml
index e29aa3907..df62b3ae9 100644
--- a/.github/workflows/ubuntu_arm.yml
+++ b/.github/workflows/ubuntu_arm.yml
@@ -9,6 +9,10 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+
+ concurrency:
+ group: ${{ github.head_ref }}-UbuntuArm
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
diff --git a/.github/workflows/ubuntu_arm64.yml b/.github/workflows/ubuntu_arm64.yml
index be7c7e169..14abdc7ba 100644
--- a/.github/workflows/ubuntu_arm64.yml
+++ b/.github/workflows/ubuntu_arm64.yml
@@ -9,6 +9,10 @@ on:
jobs:
build:
runs-on: ubuntu-latest
+
+ concurrency:
+ group: ${{ github.head_ref }}-UbuntuArm64
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index fce3236a6..29a630ea3 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -10,11 +10,14 @@ jobs:
build:
strategy:
matrix:
- os: [windows-latest, windows-2016]
+ os: [windows-2019, windows-2022]
arch: [x64, x86]
runs-on: ${{ matrix.os }}
+ concurrency:
+ group: ${{ github.head_ref }}-${{ matrix.os }}-${{ matrix.arch }}-Windows
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
with:
@@ -32,6 +35,17 @@ jobs:
- uses: little-core-labs/[email protected]
id: tagName
+ # Force xmake to a specific folder (for cache)
+ - name: Set xmake package cache path
+ run: echo "XMAKE_PKG_CACHEDIR=$(pwd)/xmake-cache" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
+
+ # Cache xmake dependencies
+ - name: Retrieve xmake cache for packages
+ uses: actions/cache@v2
+ with:
+ path: xmake-cache
+ key: ${{ matrix.os }}-${{ matrix.arch }}
+
- name: Prepare
run: |
xmake show
@@ -54,6 +68,7 @@ jobs:
Copy-Item ./core/build/xmake.exe ./xmake
Copy-Item ./scripts/xrepo.bat ./xmake
Copy-Item ./scripts/xrepo.ps1 ./xmake
+ $Env:XMAKE_MAIN_REPO = "https://github.com/xmake-io/xmake-repo.git"
$Env:XMAKE_PROGRAM_DIR = $(Resolve-Path ./xmake)
Set-Item -Path Env:Path -Value ($Env:XMAKE_PROGRAM_DIR + ";" + $Env:Path)
xrepo --version
@@ -76,10 +91,10 @@ jobs:
Expand-Archive ./7zip.zip -DestinationPath ./7zip
Copy-Item ./7zip/7z.exe ./winenv/bin
Copy-Item ./7zip/7z.dll ./winenv/bin
- Invoke-WebRequest "https://curl.se/windows/dl-7.75.0_3/curl-7.75.0_3-win32-mingw.zip" -UseBasicParsing -OutFile .\curl.zip
+ Invoke-WebRequest "https://curl.se/windows/dl-7.78.0_2/curl-7.78.0_2-win32-mingw.zip" -UseBasicParsing -OutFile .\curl.zip
Expand-Archive ./curl.zip -DestinationPath ./curl
- Copy-Item ./curl/curl-7.75.0-win32-mingw/bin/curl.exe ./winenv/bin
- Copy-Item ./curl/curl-7.75.0-win32-mingw/bin/curl-ca-bundle.crt ./winenv/bin
+ Copy-Item ./curl/curl-7.78.0-win32-mingw/bin/curl.exe ./winenv/bin
+ Copy-Item ./curl/curl-7.78.0-win32-mingw/bin/curl-ca-bundle.crt ./winenv/bin
$version = (Get-Command xmake/xmake.exe).FileVersionInfo
./nsis/makensis.exe /DMAJOR=$($version.ProductMajorPart) /DMINOR=$($version.ProductMinorPart) /DALTER=$($version.ProductBuildPart) /DBUILD=$($($version.ProductVersion -split '\+')[1]) /D${{ matrix.arch }} .\scripts\installer.nsi
(New-Item ./artifacts/${{env.RELEASE_NAME}} -ItemType Directory).FullName
diff --git a/.github/workflows/windows_luajit.yml b/.github/workflows/windows_luajit.yml
new file mode 100644
index 000000000..f20553055
--- /dev/null
+++ b/.github/workflows/windows_luajit.yml
@@ -0,0 +1,121 @@
+name: Windows (Luajit)
+
+on:
+ pull_request:
+ push:
+ release:
+ types: [published]
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os: [windows-2019, windows-2022]
+ arch: [x64, x86]
+
+ runs-on: ${{ matrix.os }}
+
+ concurrency:
+ group: ${{ github.head_ref }}-${{ matrix.os }}-${{ matrix.arch }}-Windows-Luajit
+ cancel-in-progress: true
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ # WyriHaximus/github-action-get-previous-tag@master need it
+ fetch-depth: 0
+ submodules: true
+ - uses: xmake-io/github-action-setup-xmake@v1
+ with:
+ # this is not supported, use dev branch instead
+ # xmake-version: local#
+ xmake-version: branch@dev
+ - uses: dlang-community/setup-dlang@v1
+ with:
+ compiler: dmd-latest
+ - uses: little-core-labs/[email protected]
+ id: tagName
+
+ - name: Prepare
+ run: |
+ xmake show
+ Invoke-WebRequest "https://github.com/xmake-mirror/nsis/releases/download/v30b3/nsis-3.04.zip" -UseBasicParsing -OutFile ./nsis.zip
+ Invoke-WebRequest "https://github.com/xmake-mirror/nsis/releases/download/v30b3/nsis-3.04-strlen_8192.zip" -UseBasicParsing -OutFile ./nsis-longstr.zip
+ Invoke-WebRequest "https://github.com/xmake-mirror/nsis/releases/download/v30b3/UAC.zip" -UseBasicParsing -OutFile ./nsis-uac.zip
+ Expand-Archive ./nsis.zip -DestinationPath ./nsis
+ Move-Item ./nsis/*/* ./nsis
+ Expand-Archive ./nsis-longstr.zip -DestinationPath ./nsis -Force
+ Expand-Archive ./nsis-uac.zip -DestinationPath ./nsis -Force
+ Move-Item ./nsis/UAC.nsh ./nsis/Include/
+
+ - name: Build
+ run: |
+ xmake f -vD -P core -a ${{ matrix.arch }} --runtime=luajit
+ xmake -vD -P core
+
+ - name: Tests
+ run: |
+ Copy-Item ./core/build/xmake.exe ./xmake
+ Copy-Item ./scripts/xrepo.bat ./xmake
+ Copy-Item ./scripts/xrepo.ps1 ./xmake
+ $Env:XMAKE_PROGRAM_DIR = $(Resolve-Path ./xmake)
+ Set-Item -Path Env:Path -Value ($Env:XMAKE_PROGRAM_DIR + ";" + $Env:Path)
+ xrepo --version
+ xmake show
+ xmake lua -v -D tests/run.lua
+
+ - name: Set release arch name
+ run: |
+ if ("${{ matrix.arch }}" -eq "x64") {
+ Write-Output "RELEASE_NAME=win64" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf-8 -Append
+ } else {
+ Write-Output "RELEASE_NAME=win32" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf-8 -Append
+ }
+ - name: Artifact
+ run: |
+ # build installer
+ (New-Item ./winenv/bin -ItemType Directory).FullName
+ Invoke-WebRequest "https://github.com/xmake-mirror/7zip/releases/download/19.00/7z19.00-${{ matrix.arch }}.zip" -UseBasicParsing -OutFile .\7zip.zip
+ Expand-Archive ./7zip.zip -DestinationPath ./7zip
+ Copy-Item ./7zip/7z.exe ./winenv/bin
+ Copy-Item ./7zip/7z.dll ./winenv/bin
+ Invoke-WebRequest "https://curl.se/windows/dl-7.78.0_2/curl-7.78.0_2-win32-mingw.zip" -UseBasicParsing -OutFile .\curl.zip
+ Expand-Archive ./curl.zip -DestinationPath ./curl
+ Copy-Item ./curl/curl-7.78.0-win32-mingw/bin/curl.exe ./winenv/bin
+ Copy-Item ./curl/curl-7.78.0-win32-mingw/bin/curl-ca-bundle.crt ./winenv/bin
+ $version = (Get-Command xmake/xmake.exe).FileVersionInfo
+ ./nsis/makensis.exe /DMAJOR=$($version.ProductMajorPart) /DMINOR=$($version.ProductMinorPart) /DALTER=$($version.ProductBuildPart) /DBUILD=$($($version.ProductVersion -split '\+')[1]) /D${{ matrix.arch }} .\scripts\installer.nsi
+ (New-Item ./artifacts/${{env.RELEASE_NAME}} -ItemType Directory).FullName
+ Copy-Item scripts/xmake.exe ./artifacts/${{env.RELEASE_NAME}}/xmake.exe
+ # archive
+ Copy-Item ./*.md ./xmake
+ Copy-Item ./winenv ./xmake -Recurse
+ Add-Type -AssemblyName System.Text.Encoding
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+ class FixedEncoder : System.Text.UTF8Encoding {
+ FixedEncoder() : base($true) { }
+ [byte[]] GetBytes([string] $s)
+ {
+ $s = $s.Replace("\", "/")
+ return ([System.Text.UTF8Encoding]$this).GetBytes($s)
+ }
+ }
+ Copy-Item ./xmake ./archive/xmake -Recurse
+ [System.IO.Compression.ZipFile]::CreateFromDirectory("$PWD\archive", "$PWD\archive.zip", [System.IO.Compression.CompressionLevel]::Optimal, $false, [FixedEncoder]::new())
+ (Get-FileHash .\archive.zip -Algorithm SHA256).Hash.ToLower() + " *xmake.zip`n" | Out-File ./shafile -Encoding ASCII -NoNewLine -Append
+ Copy-Item archive.zip ./artifacts/${{env.RELEASE_NAME}}
+ Copy-Item shafile ./artifacts/${{env.RELEASE_NAME}}
+
+ # upload artifacts
+ - uses: actions/upload-artifact@v2
+ with:
+ name: xmake-latest.${{env.RELEASE_NAME}}.exe
+ path: artifacts/${{env.RELEASE_NAME}}/xmake.exe
+ - uses: actions/upload-artifact@v2
+ with:
+ name: xmake-latest.${{ env.RELEASE_NAME }}.zip
+ path: artifacts/${{env.RELEASE_NAME}}/archive.zip
+ - uses: actions/upload-artifact@v2
+ with:
+ name: xmake-latest.${{ env.RELEASE_NAME }}.sha256
+ path: artifacts/${{env.RELEASE_NAME}}/shafile
+
diff --git a/.gitignore b/.gitignore
index 1631dd04d..b9f47f1b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,9 @@
.xmake/
build/
+# gcc cache
+gcm.cache
+
# for VS Code
.vscode/
@@ -47,3 +50,12 @@ compile_commands.json
/scripts/rpmbuild/SRPMS/*
!/xmake/actions/build/
+
+# for linux driver
+*.o
+*.ko
+*.mod
+.*.cmd
+*.mod.c
+Module.symvers
+modules.order
diff --git a/.gitmodules b/.gitmodules
index ac5f4dde3..4e2703e2b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,3 +13,6 @@
[submodule "core/src/lua-cjson/lua-cjson"]
path = core/src/lua-cjson/lua-cjson
url = ../../xmake-io/xmake-core-lua-cjson.git
+[submodule "core/src/lua/lua"]
+ path = core/src/lua/lua
+ url = ../../xmake-io/xmake-core-lua.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 756b3021d..952094f40 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,12 +4,141 @@
### New features
+* [#1298](https://github.com/xmake-io/xmake/issues/1928): Support vcpkg manifest mode and select version for package/install
+* [#1896](https://github.com/xmake-io/xmake/issues/1896): Add `python.library` rule to build pybind modules
+* [#1939](https://github.com/xmake-io/xmake/issues/1939): Add `remove_files`, `remove_headerfiles` and mark `del_files` as deprecated
+* Made on_config as the official api for rule/target
+
+### Changes
+
+* [#1923](https://github.com/xmake-io/xmake/issues/1923): Improve to build linux driver, support set custom linux-headers path
+* [#1962](https://github.com/xmake-io/xmake/issues/1962): Improve armclang toolchain to support to build asm
+
+### Bugs fixed
+
+* [#1875](https://github.com/xmake-io/xmake/issues/1875): Fix deploy android qt apk issue
+
+## v2.6.2
+
+### New features
+
+* [#1902](https://github.com/xmake-io/xmake/issues/1902): Support to build linux kernel driver modules
+* [#1913](https://github.com/xmake-io/xmake/issues/1913): Build and run targets with given group pattern
+
+### Change
+
+* [#1872](https://github.com/xmake-io/xmake/issues/1872): Escape characters for set_configvar
+* [#1888](https://github.com/xmake-io/xmake/issues/1888): Improve windows installer to avoid remove other files
+* [#1895](https://github.com/xmake-io/xmake/issues/1895): Improve `plugin.vsxmake.autoupdate` rule
+* [#1893](https://github.com/xmake-io/xmake/issues/1893): Improve to detect icc and ifort toolchains
+* [#1905](https://github.com/xmake-io/xmake/pull/1905): Add support of external headers without experimental for msvc
+* [#1904](https://github.com/xmake-io/xmake/pull/1904): Improve vs201x generator
+* Add `XMAKE_THEME` envirnoment variable to switch theme
+* [#1907](https://github.com/xmake-io/xmake/issues/1907): Add `-f/--force` to force to create project in a non-empty directory
+* [#1917](https://github.com/xmake-io/xmake/pull/1917): Improve to find_package and configurations
+
+### Bugs fixed
+
+* [#1885](https://github.com/xmake-io/xmake/issues/1885): Fix package:fetch_linkdeps
+* [#1903](https://github.com/xmake-io/xmake/issues/1903): Fix package link order
+
+## v2.6.1
+
+### New features
+
+* [#1799](https://github.com/xmake-io/xmake/issues/1799): Support mixed rust & c++ target and cargo dependences
+* Add `utils.glsl2spv` rules to compile *.vert/*.frag shader files to spirv file and binary c header file
+
+### Changes
+
+* Switch to Lua5.4 runtime by default
+* [#1776](https://github.com/xmake-io/xmake/issues/1776): Improve system::find_package, support to find package from envs
+* [#1786](https://github.com/xmake-io/xmake/issues/1786): Improve apt:find_package, support to find alias package
+* [#1819](https://github.com/xmake-io/xmake/issues/1819): Add precompiled header to cmake generator
+* Improve C++20 module to support std libraries for msvc
+* [#1792](https://github.com/xmake-io/xmake/issues/1792): Add custom command in vs project generator
+* [#1835](https://github.com/xmake-io/xmake/issues/1835): Improve MDK program supports and add `set_runtimes("microlib")`
+* [#1858](https://github.com/xmake-io/xmake/issues/1858): Improve to build c++20 modules with libraries
+* Add $XMAKE_BINARY_REPO and $XMAKE_MAIN_REPO repositories envs
+* [#1865](https://github.com/xmake-io/xmake/issues/1865): Improve openmp projects
+* [#1845](https://github.com/xmake-io/xmake/issues/1845): Install pdb files for static library
+
+### Bugs Fixed
+
+* Fix semver to parse build string with zero prefix
+* [#50](https://github.com/libbpf/libbpf-bootstrap/issues/50): Fix rule and build bpf program errors
+* [#1610](https://github.com/xmake-io/xmake/issues/1610): Fix `xmake f --menu` not responding in vscode and support ConPTY terminal virtkeys
+
+## v2.5.9
+
+### New features
+
+* [#1736](https://github.com/xmake-io/xmake/issues/1736): Support wasi-sdk toolchain
+* Support Lua 5.4 runtime
+* Add gcc-8, gcc-9, gcc-10, gcc-11 toolchains
+* [#1623](https://github.com/xmake-io/xmake/issues/1632): Support find_package from cmake
+* [#1747](https://github.com/xmake-io/xmake/issues/1747): Add `set_kind("headeronly")` for target to install files for headeronly library
+* [#1019](https://github.com/xmake-io/xmake/issues/1019): Support Unity build
+* [#1438](https://github.com/xmake-io/xmake/issues/1438): Support code amalgamation, `xmake l cli.amalgamate`
+* [#1765](https://github.com/xmake-io/xmake/issues/1756): Support nim language
+* [#1762](https://github.com/xmake-io/xmake/issues/1762): Manage and switch the given package envs for `xrepo env`
+* [#1767](https://github.com/xmake-io/xmake/issues/1767): Support Circle compiler
+* [#1753](https://github.com/xmake-io/xmake/issues/1753): Support armcc/armclang toolchains for Keil/MDK
+* [#1774](https://github.com/xmake-io/xmake/issues/1774): Add table.contains api
+* [#1735](https://github.com/xmake-io/xmake/issues/1735): Add custom command in cmake generator
+
+### Changes
+
+* [#1528](https://github.com/xmake-io/xmake/issues/1528): Check c++17/20 features
+* [#1729](https://github.com/xmake-io/xmake/issues/1729): Improve C++20 modules for clang/gcc/msvc, support inter-module dependency compilation and parallel optimization
+* [#1779](https://github.com/xmake-io/xmake/issues/1779): Remove builtin `-Gd` for ml.exe/x86
+* [#1781](https://github.com/xmake-io/xmake/issues/1781): Improve get.sh installation script to support nixos
+
+## v2.5.8
+
+### New features
+
+* [#388](https://github.com/xmake-io/xmake/issues/388): Pascal Language Support
+* [#1682](https://github.com/xmake-io/xmake/issues/1682): Add optional lua5.3 backend instead of luajit to provide better compatibility
+* [#1622](https://github.com/xmake-io/xmake/issues/1622): Support Swig
+* [#1714](https://github.com/xmake-io/xmake/issues/1714): Support build local embed cmake projects
+* [#1715](https://github.com/xmake-io/xmake/issues/1715): Support to detect compiler language standards as features and add `check_macros`
+* Support Loongarch
+
+### Change
+
+* [#1618](https://github.com/xmake-io/xmake/issues/1618): Improve vala to support to generate libraries and bindings
+* Improve Qt rules to support Qt 4.x
+* Improve `set_symbols("debug")` to generate pdb file for clang on windows
+* [#1638](https://github.com/xmake-io/xmake/issues/1638): Improve to merge static library
+* Improve on_load/after_load to support to add target deps dynamically
+* [#1675](https://github.com/xmake-io/xmake/pull/1675): Rename dynamic and import library suffix for mingw
+* [#1694](https://github.com/xmake-io/xmake/issues/1694): Support to define a variable without quotes for configuration files
+* Support Android NDK r23
+* Add `c++latest` and `clatest` for `set_languages`
+* [#1720](https://github.com/xmake-io/xmake/issues/1720): Add `save_scope` and `restore_scope` to fix `check_xxx` apis
+* [#1726](https://github.com/xmake-io/xmake/issues/1726): Improve compile_commands generator to support nvcc
+
+### Bugs fixed
+
+* [#1671](https://github.com/xmake-io/xmake/issues/1671): Fix incorrect absolute path after installing precompiled packages
+* [#1689](https://github.com/xmake-io/xmake/issues/1689): Fix unicode chars bug for vsxmake
+
+## v2.5.7
+
+### New features
+
* [#1534](https://github.com/xmake-io/xmake/issues/1534): Support to compile Vala lanuage project
* [#1544](https://github.com/xmake-io/xmake/issues/1544): Add utils.bin2c rule to generate header from binary file
+* [#1547](https://github.com/xmake-io/xmake/issues/1547): Support to run and get output of c/c++ snippets in option
+* [#1567](https://github.com/xmake-io/xmake/issues/1567): Package "lock file" support to freeze dependencies
+* [#1597](https://github.com/xmake-io/xmake/issues/1597): Support to compile *.metal files to generate *.metalib and improve xcode.application rule
### Change
* [#1540](https://github.com/xmake-io/xmake/issues/1540): Better support for compilation of automatically generated code
+* [#1578](https://github.com/xmake-io/xmake/issues/1578): Improve add_repositories to support relative path better
+* [#1582](https://github.com/xmake-io/xmake/issues/1582): Improve installation and os.cp to reserve symlink
### Bugs fixed
@@ -1055,12 +1184,141 @@
### 新特性
+* [#1298](https://github.com/xmake-io/xmake/issues/1928): 支持 vcpkg 清单模式安装包,实现安装包的版本选择
+* [#1896](https://github.com/xmake-io/xmake/issues/1896): 添加 `python.library` 规则去构建 pybind 模块,并且支持 soabi
+* [#1939](https://github.com/xmake-io/xmake/issues/1939): 添加 `remove_files`, `remove_headerfiles` 并且标记 `del_files` 作为废弃接口
+* 将 on_config 作为正式的公开接口,用于 target 和 rule
+
+### 改进
+
+* [#1923](https://github.com/xmake-io/xmake/issues/1923): 改进构建 linux 驱动,支持设置自定义 linux-headers 路径
+* [#1962](https://github.com/xmake-io/xmake/issues/1962): 改进 armclang 工具链去支持构建 asm
+
+### Bugs 修复
+
+* [#1875](https://github.com/xmake-io/xmake/issues/1875): 修复部署生成 Android Qt 程序包失败问题
+
+## v2.6.2
+
+### 新特性
+
+* [#1902](https://github.com/xmake-io/xmake/issues/1902): 支持构建 linux 内核驱动模块
+* [#1913](https://github.com/xmake-io/xmake/issues/1913): 通过 group 模式匹配,指定构建和运行一批目标程序
+
+### 改进
+
+* [#1872](https://github.com/xmake-io/xmake/issues/1872): 支持转义 set_configvar 中字符串值
+* [#1888](https://github.com/xmake-io/xmake/issues/1888): 改进 windows 安装器,避免错误删除其他安装目录下的文件
+* [#1895](https://github.com/xmake-io/xmake/issues/1895): 改进 `plugin.vsxmake.autoupdate` 规则
+* [#1893](https://github.com/xmake-io/xmake/issues/1893): 改进探测 icc 和 ifort 工具链
+* [#1905](https://github.com/xmake-io/xmake/pull/1905): 改进 msvc 对 external 头文件搜索探测支持
+* [#1904](https://github.com/xmake-io/xmake/pull/1904): 改进 vs201x 工程生成器
+* 添加 `XMAKE_THEME` 环境变量去切换主题配置
+* [#1907](https://github.com/xmake-io/xmake/issues/1907): 添加 `-f/--force` 参数使得 `xmake create` 可以在费控目录被强制创建
+* [#1917](https://github.com/xmake-io/xmake/pull/1917): 改进 find_package 和配置
+
+### Bugs 修复
+
+* [#1885](https://github.com/xmake-io/xmake/issues/1885): 修复 package:fetch_linkdeps 链接顺序问题
+* [#1903](https://github.com/xmake-io/xmake/issues/1903): 修复包链接顺序
+
+## v2.6.1
+
+### 新特性
+
+* [#1799](https://github.com/xmake-io/xmake/issues/1799): 支持混合 Rust 和 C++ 程序,以及集成 Cargo 依赖库
+* 添加 `utils.glsl2spv` 规则去编译 *.vert/*.frag shader 文件生成 spirv 文件和二进制 C 头文件
+
+### 改进
+
+* 默认切换到 Lua5.4 运行时
+* [#1776](https://github.com/xmake-io/xmake/issues/1776): 改进 system::find_package,支持从环境变量中查找系统库
+* [#1786](https://github.com/xmake-io/xmake/issues/1786): 改进 apt:find_package,支持查找 alias 包
+* [#1819](https://github.com/xmake-io/xmake/issues/1819): 添加预编译头到 cmake 生成器
+* 改进 C++20 Modules 为 msvc 支持 std 标准库
+* [#1792](https://github.com/xmake-io/xmake/issues/1792): 添加自定义命令到 vs 工程生成器
+* [#1835](https://github.com/xmake-io/xmake/issues/1835): 改进 MDK 程序构建支持,增加 `set_runtimes("microlib")`
+* [#1858](https://github.com/xmake-io/xmake/issues/1858): 改进构建 c++20 modules,修复跨 target 构建问题
+* 添加 $XMAKE_BINARY_REPO 和 $XMAKE_MAIN_REPO 仓库设置环境变量
+* [#1865](https://github.com/xmake-io/xmake/issues/1865): 改进 openmp 工程
+* [#1845](https://github.com/xmake-io/xmake/issues/1845): 为静态库安装 pdb 文件
+
+### Bugs 修复
+
+* 修复语义版本中解析带有 0 前缀的 build 字符串问题
+* [#50](https://github.com/libbpf/libbpf-bootstrap/issues/50): 修复 rule 和构建 bpf 程序 bug
+* [#1610](https://github.com/xmake-io/xmake/issues/1610): 修复 `xmake f --menu` 在 vscode 终端下按键无响应,并且支持 ConPTY 终端虚拟按键
+
+## v2.5.9
+
+### 新特性
+
+* [#1736](https://github.com/xmake-io/xmake/issues/1736): 支持 wasi-sdk 工具链
+* 支持 Lua 5.4 运行时
+* 添加 gcc-8, gcc-9, gcc-10, gcc-11 工具链
+* [#1623](https://github.com/xmake-io/xmake/issues/1632): 支持 find_package 从 cmake 查找包
+* [#1747](https://github.com/xmake-io/xmake/issues/1747): 添加 `set_kind("headeronly")` 更好的处理 headeronly 库的安装
+* [#1019](https://github.com/xmake-io/xmake/issues/1019): 支持 Unity build
+* [#1438](https://github.com/xmake-io/xmake/issues/1438): 增加 `xmake l cli.amalgamate` 命令支持代码合并
+* [#1765](https://github.com/xmake-io/xmake/issues/1756): 支持 nim 语言
+* [#1762](https://github.com/xmake-io/xmake/issues/1762): 为 `xrepo env` 管理和切换指定的环境配置
+* [#1767](https://github.com/xmake-io/xmake/issues/1767): 支持 Circle 编译器
+* [#1753](https://github.com/xmake-io/xmake/issues/1753): 支持 Keil/MDK 的 armcc/armclang 工具链
+* [#1774](https://github.com/xmake-io/xmake/issues/1774): 添加 table.contains api
+* [#1735](https://github.com/xmake-io/xmake/issues/1735): 添加自定义命令到 cmake 生成器
+* [#1781](https://github.com/xmake-io/xmake/issues/1781): 改进 get.sh 安装脚本支持 nixos
+
+### 改进
+
+* [#1528](https://github.com/xmake-io/xmake/issues/1528): 检测 c++17/20 特性
+* [#1729](https://github.com/xmake-io/xmake/issues/1729): 改进 C++20 modules 对 clang/gcc/msvc 的支持,支持模块间依赖编译和并行优化
+* [#1779](https://github.com/xmake-io/xmake/issues/1779): 改进 ml.exe/x86,移除内置的 `-Gd` 选项
+
+## v2.5.8
+
+### 新特性
+
+* [#388](https://github.com/xmake-io/xmake/issues/388): Pascal 语言支持,可以使用 fpc 来编译 free pascal
+* [#1682](https://github.com/xmake-io/xmake/issues/1682): 添加可选的额lua5.3 运行时替代 luajit,提供更好的平台兼容性。
+* [#1622](https://github.com/xmake-io/xmake/issues/1622): 支持 Swig
+* [#1714](https://github.com/xmake-io/xmake/issues/1714): 支持内置 cmake 等第三方项目的混合编译
+* [#1715](https://github.com/xmake-io/xmake/issues/1715): 支持探测编译器语言标准特性,并且新增 `check_macros` 检测接口
+* xmake 支持在 Loongarch 架构上运行
+
+### 改进
+
+* [#1618](https://github.com/xmake-io/xmake/issues/1618): 改进 vala 支持构建动态库和静态库程序
+* 改进 Qt 规则去支持 Qt 4.x
+* 改进 `set_symbols("debug")` 支持 clang/windows 生成 pdb 文件
+* [#1638](https://github.com/xmake-io/xmake/issues/1638): 改进合并静态库
+* 改进 on_load/after_load 去支持动态的添加 target deps
+* [#1675](https://github.com/xmake-io/xmake/pull/1675): 针对 mingw 平台,重命名动态库和导入库文件名后缀
+* [#1694](https://github.com/xmake-io/xmake/issues/1694): 支持在 set_configvar 中定义一个不带引号的字符串变量
+* 改进对 Android NDK r23 的支持
+* 为 `set_languages` 新增 `c++latest` 和 `clatest` 配置值
+* [#1720](https://github.com/xmake-io/xmake/issues/1720): 添加 `save_scope` 和 `restore_scope` 去修复 `check_xxx` 相关接口
+* [#1726](https://github.com/xmake-io/xmake/issues/1726): 改进 compile_commands 生成器去支持 nvcc
+
+### Bugs 修复
+
+* [#1671](https://github.com/xmake-io/xmake/issues/1671): 修复安装预编译包后,*.cmake 里面的一些不正确的绝对路径
+* [#1689](https://github.com/xmake-io/xmake/issues/1689): 修复 vsxmake 插件的 unicode 字符显示和加载问题
+
+## v2.5.7
+
+### 新特性
+
* [#1534](https://github.com/xmake-io/xmake/issues/1534): 新增对 Vala 语言的支持
* [#1544](https://github.com/xmake-io/xmake/issues/1544): 添加 utils.bin2c 规则去自动从二进制资源文件产生 .h 头文件并引入到 C/C++ 代码中
+* [#1547](https://github.com/xmake-io/xmake/issues/1547): option/snippets 支持运行检测模式,并且可以获取输出
+* [#1567](https://github.com/xmake-io/xmake/issues/1567): 新增 xmake-requires.lock 包依赖锁定支持
+* [#1597](https://github.com/xmake-io/xmake/issues/1597): 支持编译 metal 文件到 metallib,并改进 xcode.application 规则去生成内置的 default.metallib 到 app
### 改进
* [#1540](https://github.com/xmake-io/xmake/issues/1540): 更好更方便地编译自动生成的代码
+* [#1578](https://github.com/xmake-io/xmake/issues/1578): 改进 add_repositories 去更好地支持相对路径
+* [#1582](https://github.com/xmake-io/xmake/issues/1582): 改进安装和 os.cp 支持符号链接
### Bugs 修复
@@ -2098,3 +2356,5 @@
* 修复set_installscript接口的一些bug
* 修复在windows x86_64下,安装失败的问题
* 修复相对路径的一些bug
+
+
diff --git a/NOTICE.md b/NOTICE.md
index 7cde1df09..8a85b751e 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -45,6 +45,14 @@ which can be obtained at:
* HOMEPAGE:
* http://luajit.org/
+This product depends on 'Lua', The Lua Programing Language,
+which can be obtained at:
+
+ * LICENSE:
+ * https://www.lua.org/license.html (MIT License)
+ * HOMEPAGE:
+ * http://lua.org/
+
This product depends on 'tbox', The Treasure Box Library,
which can be obtained at:
diff --git a/README.md b/README.md
index 53b0fa027..ade03e163 100644
--- a/README.md
+++ b/README.md
@@ -7,13 +7,13 @@
<div>
<a href="https://github.com/xmake-io/xmake/actions?query=workflow%3AWindows">
- <img src="https://img.shields.io/github/workflow/status/xmake-io/xmake/Windows/dev.svg?style=flat-square&logo=windows" alt="github-ci" />
+ <img src="https://img.shields.io/github/workflow/status/xmake-io/xmake/Windows/master.svg?style=flat-square&logo=windows" alt="github-ci" />
</a>
<a href="https://github.com/xmake-io/xmake/actions?query=workflow%3ALinux">
- <img src="https://img.shields.io/github/workflow/status/xmake-io/xmake/Linux/dev.svg?style=flat-square&logo=linux" alt="github-ci" />
+ <img src="https://img.shields.io/github/workflow/status/xmake-io/xmake/Linux/master.svg?style=flat-square&logo=linux" alt="github-ci" />
</a>
<a href="https://github.com/xmake-io/xmake/actions?query=workflow%3AmacOS">
- <img src="https://img.shields.io/github/workflow/status/xmake-io/xmake/macOS/dev.svg?style=flat-square&logo=apple" alt="github-ci" />
+ <img src="https://img.shields.io/github/workflow/status/xmake-io/xmake/macOS/master.svg?style=flat-square&logo=apple" alt="github-ci" />
</a>
<a href="https://github.com/xmake-io/xmake/releases">
<img src="https://img.shields.io/github/release/xmake-io/xmake.svg?style=flat-square" alt="Github All Releases" />
@@ -60,9 +60,17 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
## Introduction ([中文](/README_zh.md))
-xmake is a lightweight cross-platform build utility based on Lua. It uses xmake.lua to maintain project builds. Compared with makefile/CMakeLists.txt, the configuration syntax is more concise and intuitive. It is very friendly to novices and can quickly get started in a short time. Let users focus more on actual project development.
+Xmake is a lightweight cross-platform build utility based on Lua.
-It can compile the project directly like Make/Ninja, or generate project files like CMake/Meson, and it also has a built-in package management system to help users solve the integrated use of C/C++ dependent libraries.
+It is very lightweight and has no dependencies because it has a built-in Lua runtime.
+
+It uses xmake.lua to maintain project builds and its configuration syntax is very simple and readable.
+
+We can use it to build project directly like Make/Ninja, or generate project files like CMake/Meson, and it also has a built-in package management system to help users solve the integrated use of C/C++ dependent libraries.
+
+```
+Xmake = Build backend + Project Generator + Package Manager
+```
If you want to know more, please refer to: [Documents](https://xmake.io/#/getting_started), [Github](https://github.com/xmake-io/xmake) and [Gitee](https://gitee.com/tboox/xmake) and also welcome to join our [community](https://xmake.io/#/about/contact).
@@ -177,6 +185,19 @@ The test project: [xmake-core](https://github.com/xmake-io/xmake/tree/master/cor
* Clib (clib::clibs/[email protected])
* Dub (dub::log 0.4.3)
* Portage on Gentoo/Linux (portage::libhandy)
+* Nimble for nimlang (nimble::zip >1.3)
+* Cargo for rust (cargo::base64 0.13.0)
+
+### Package management features
+
+* The official repository provides nearly 500+ packages, one-click compilation on all platforms
+* Full platform package support, support for cross-compiled dependent package integration
+* Support package virtual environment, `xrepo env shell`
+* Precompiled package acceleration for windows
+* Support self-built package repositories, private repository deployment
+* Third-party package repository support, such as: vcpkg, conan, conda, etc.
+* Support to pull using remote toolchain automatically
+* Support to lock package dependency
## Supported platforms
@@ -199,7 +220,7 @@ The test project: [xmake-core](https://github.com/xmake-io/xmake/tree/master/cor
```bash
$ xmake show -l toolchains
xcode Xcode IDE
-vs VisualStudio IDE
+msvc Microsoft Visual C/C++ Compiler
yasm The Yasm Modular Assembler
clang A C language family frontend for LLVM
go Go Programming Language Compiler
@@ -222,7 +243,13 @@ tinycc Tiny C Compiler
emcc A toolchain for compiling to asm.js and WebAssembly
icc Intel C/C++ Compiler
ifort Intel Fortran Compiler
-muslcc The musl-based cross-compilation toolchains
+muslcc The musl-based cross-compilation toolchain
+fpc Free Pascal Programming Language Compiler
+wasi WASI-enabled WebAssembly C/C++ toolchain
+nim Nim Programming Language Compiler
+circle A new C++20 compiler
+armcc ARM Compiler Version 5 of Keil MDK
+armclang ARM Compiler Version 6 of Keil MDK
```
## Supported Languages
@@ -239,26 +266,24 @@ muslcc The musl-based cross-compilation toolchains
* Cuda
* Zig
* Vala
+* Pascal
+* Nim
-## Support Features
+## Supported Features
-* Simple project configuration syntax
-* Direct build support, without relying on any third-party back-end make tools
-* Support cross platform
-* Support cross compilation
-* Multi-task parallel compilation support
-* C++20 Module-TS support
-* Support cross-platform C/C++ dependency packages
-* Support self-built distributed package repositories
-* Support the installation of cloud pre-compiled packages
-* Support third-party package repositories, such as: vcpkg, conan, conda, etc.
-* Support multi-language mixed compilation
-* Flexible lua scripts, rich extension modules
-* Support for generating vsproj/cmake/makefile/compile_commands files
+* The configuration grammar is simple and easy to use
+* Quick installation, without any dependencies
+* One-click compilation for all platforms
+* Support cross compilation, intelligent analysis of cross tool chain information
+* Extremely fast, multi-task parallel compilation support
+* C++20 Module support
+* Support cross-platform C/C++ dependency package quick integration, built-in package manager
+* Multi-language mixed compilation support
+* Rich plug-in support, providing various project generators, such as: vs/makefile/cmakelists/compile_commands to generate plugins
* REPL interactive execution support
-* Incremental compilation support, automatic analysis of header dependency files
-* Fast switching toolchains
-* Automatic pull toolchain and dependency package integration
+* Incremental compilation support, automatic analysis of header files
+* Quick switching and customization support of tool chain
+* A large number of expansion modules support
## Supported Projects
@@ -270,8 +295,14 @@ muslcc The musl-based cross-compilation toolchains
* WDK Driver (umdf/kmdf/wdm)
* WinSDK Application
* MFC Application
-* iOS/MacOS Application
+* iOS/MacOS Application (Support .metal)
* Framework and Bundle Program (iOS/MacOS)
+* SWIG Modules (Lua, python, ...)
+* Luarocks Modules
+* Protobuf Program
+* Lex/yacc program
+* C++20 Modules
+* Linux Kernel Driver Modules
## More Examples
@@ -431,11 +462,11 @@ target("test")
## Plugins
-#### Generate IDE project file plugin(makefile, vs2002 - vs2019 .. )
+#### Generate IDE project file plugin(makefile, vs2002 - vs2022 .. )
```bash
-$ xmake project -k vsxmake -m "debug;release" # New vsproj generator (Recommended)
-$ xmake project -k vs -m "debug;release"
+$ xmake project -k vsxmake -m "debug,release" # New vsproj generator (Recommended)
+$ xmake project -k vs -m "debug,release"
$ xmake project -k cmake
$ xmake project -k ninja
$ xmake project -k compile_commands
@@ -477,13 +508,17 @@ Please download and install more other plugins from the plugins repository [xmak
* [xmake.vim](https://github.com/luzhlon/xmake.vim) (third-party, thanks [@luzhlon](https://github.com/luzhlon))
+* [xmake-visualstudio](https://github.com/HelloWorld886/xmake-visualstudio) (third-party, thanks [@HelloWorld886](https://github.com/HelloWorld886))
+
+* [xmake-qtcreator](https://github.com/Arthapz/xmake-project-manager) (third-party, thanks [@Arthapz](https://github.com/Arthapz))
+
### XMake Gradle Plugin (JNI)
We can uses [xmake-gradle](https://github.com/xmake-io/xmake-gradle) plugin to compile JNI library in gradle.
```
plugins {
- id 'org.tboox.gradle-xmake-plugin' version '1.1.4'
+ id 'org.tboox.gradle-xmake-plugin' version '1.1.5'
}
android {
diff --git a/README_zh.md b/README_zh.md
index 61f5ad93a..9776597ea 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -60,11 +60,19 @@
## 简介
-xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
+Xmake 是一个基于 Lua 的轻量级跨平台构建工具。
-虽然,简单易用是 xmake 的一大特色,但 xmake 的功能也是非常强大的,既能够像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,还有内置的包管理系统来帮助用户解决 C/C++依赖库的集成使用问题。
+它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
-目前,xmake主要用于C/C++项目的构建,但是同时也支持其他native语言的构建,可以实现跟C/C++进行混合编译,同时编译速度也是非常的快,可以跟Ninja持平。
+它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
+
+我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
+
+目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
+
+```
+Xmake = Build backend + Project Generator + Package Manager
+```
如果你想要了解更多,请参考:[在线文档](https://xmake.io/#/zh-cn/getting_started), [Github](https://github.com/xmake-io/xmake)以及[Gitee](https://gitee.com/tboox/xmake),同时也欢迎加入我们的 [社区](https://xmake.io/#/zh-ch/about/contact).
@@ -185,6 +193,20 @@ $ xmake f --menu
* Apt on ubuntu/debian (apt::zlib1g-dev)
* Clib (clib::clibs/[email protected])
* Dub (dub::log 0.4.3)
+* Portage on Gentoo/Linux (portage::libhandy)
+* Nimble for nimlang (nimble::zip >1.3)
+* Cargo for rust (cargo::base64 0.13.0)
+
+### 包管理特性
+
+* 官方仓库提供近 500+ 常用包,真正做到全平台一键下载集成编译
+* 全平台包支持,支持交叉编译的依赖包集成
+* 支持包虚拟环境管理和加载,`xrepo env shell`
+* Windows 云端预编译包加速
+* 支持自建包仓库,私有仓库部署
+* 第三方包仓库支持,提供更加丰富的包源,例如:vcpkg, conan, conda 等等
+* 支持自动拉取使用云端工具链
+* 支持包依赖锁定
## 支持平台
@@ -207,7 +229,7 @@ $ xmake f --menu
```bash
$ xmake show -l toolchains
xcode Xcode IDE
-vs VisualStudio IDE
+msvc Microsoft Visual C/C++ Compiler
yasm The Yasm Modular Assembler
clang A C language family frontend for LLVM
go Go Programming Language Compiler
@@ -230,7 +252,13 @@ tinycc Tiny C Compiler
emcc A toolchain for compiling to asm.js and WebAssembly
icc Intel C/C++ Compiler
ifort Intel Fortran Compiler
-muslcc The musl-based cross-compilation toolchains
+muslcc The musl-based cross-compilation toolchain
+fpc Free Pascal Programming Language Compiler
+wasi WASI-enabled WebAssembly C/C++ toolchain
+nim Nim Programming Language Compiler
+circle A new C++20 compiler
+armcc ARM Compiler Version 5 of Keil MDK
+armclang ARM Compiler Version 6 of Keil MDK
```
## 支持语言
@@ -246,38 +274,43 @@ muslcc The musl-based cross-compilation toolchains
* Cuda
* Zig
* Vala
+* Pascal
+* Nim
## 支持特性
-* 简洁的配置语法
-* 直接构建支持,不依赖任何第三方后端 make 工具
-* 跨平台支持,不同平台可方便快速地切换
-* 交叉编译支持,智能分析交叉工具链信息
-* 多任务并行编译支持
-* C++20 Module-TS 支持
-* 支持跨平台的 C/C++ 依赖包快速集成
-* 自建分布式包仓库,支持安装云端预编译包
-* 第三方包仓库支持,例如:vcpkg, conan, conda 等等
+* 语法简单易上手
+* 快速安装,无任何依赖
+* 全平台一键编译
+* 支持交叉编译,智能分析交叉工具链信息
+* 极速,多任务并行编译支持
+* C++20 Module 支持
+* 支持跨平台的 C/C++ 依赖包快速集成,内置包管理器
* 多语言混合编译支持
-* 灵活的 lua 脚本,丰富的扩展模块,可实现高度定制化
-* 丰富的插件支持,内置 vs/cmake/makefile/compile_commands 等生成插件
+* 丰富的插件支持,提供各种工程生成器,例如:vs/makefile/cmakelists/compile_commands 生成插件
* REPL 交互式执行支持
* 增量编译支持,头文件依赖自动分析
* 工具链的快速切换、定制化支持
-* 自动拉取工具链以及依赖包的快速整合
+* 丰富的扩展模块支持
## 工程类型
* 静态库程序
* 动态库类型
* 控制台程序
-* Cuda程序
-* Qt应用程序
-* WDK驱动程序
-* WinSDK应用程序
-* MFC应用程序
-* iOS/MacOS应用程序
+* Cuda 程序
+* Qt 应用程序
+* WDK Windows 驱动程序
+* WinSDK 应用程序
+* MFC 应用程序
+* iOS/MacOS 应用程序(支持.metal)
* Framework和Bundle程序(iOS/MacOS)
+* SWIG 模块 (Lua, python, ...)
+* Luarocks 模块
+* Protobuf 程序
+* Lex/yacc 程序
+* C++20 模块
+* Linux 内核驱动模块
## 更多例子
@@ -437,11 +470,11 @@ target("test")
## 插件
-#### 生成IDE工程文件插件(makefile, vs2002 - vs2019, ...)
+#### 生成IDE工程文件插件(makefile, vs2002 - vs2022, ...)
```bash
-$ xmake project -k vsxmake -m "debug;release" # 新版vs工程生成插件(推荐)
-$ xmake project -k vs -m "debug;release"
+$ xmake project -k vsxmake -m "debug,release" # 新版vs工程生成插件(推荐)
+$ xmake project -k vs -m "debug,release"
$ xmake project -k cmake
$ xmake project -k ninja
$ xmake project -k compile_commands
@@ -483,13 +516,17 @@ $ xmake l
* [xmake.vim](https://github.com/luzhlon/xmake.vim) (third-party, thanks [@luzhlon](https://github.com/luzhlon))
+* [xmake-visualstudio](https://github.com/HelloWorld886/xmake-visualstudio) (third-party, thanks [@HelloWorld886](https://github.com/HelloWorld886))
+
+* [xmake-qtcreator](https://github.com/Arthapz/xmake-project-manager) (third-party, thanks [@Arthapz](https://github.com/Arthapz))
+
### XMake Gradle插件 (JNI)
我们也可以在Gradle中使用[xmake-gradle](https://github.com/xmake-io/xmake-gradle)插件来集成编译JNI库
```
plugins {
- id 'org.tboox.gradle-xmake-plugin' version '1.1.4'
+ id 'org.tboox.gradle-xmake-plugin' version '1.1.5'
}
android {
diff --git a/core/makefile b/core/makefile
index 0bba754cd..51c7611fa 100644
--- a/core/makefile
+++ b/core/makefile
@@ -298,6 +298,14 @@ base_LIBNAMES += $(shell if { cat detect/readline.c | $(CC) -xc - -lreadline -o
base_LIBNAMES += m dl pthread
endif
+# get branch and commit
+ifeq ($(BRANCH),)
+BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
+endif
+ifeq ($(COMMIT),)
+COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null)
+endif
+
# check jit compiler
ifeq ($(PLAT),linux)
luajit_JIT :=$(shell if [ -f "/etc/redhat-release" ]; then echo "nojit"; else echo "jit"; fi )
@@ -360,6 +368,8 @@ config : .null
@$(ECHO) " small:\t\t"$(SMALL)
@$(ECHO) " ccache:\t\t"$(CCACHE)
@$(ECHO) " distcc:\t\t"$(DISTCC)
+ @$(ECHO) " branch:\t\t"$(BRANCH)
+ @$(ECHO) " commit:\t\t"$(COMMIT)
@$(ECHO) " luajit:\t\t"$(luajit_JIT)
@$(ECHO) ""
@$(ECHO) "packages:"
@@ -368,6 +378,7 @@ config : .null
@$(ECHO) "directories:"
@$(ECHO) " install:\t\t"$(abspath $(INSTALL))
@$(ECHO) " package:\t\t"$(PACKAGE)
+ @$(ECHO) " backend:\t\t"$(RUNTIME)
@$(ECHO) ""
@$(ECHO) "toolchains:"
@$(ECHO) " bin:\t\t"$(BIN)
@@ -392,6 +403,10 @@ config : .null
@$(ECHO) "# project" >> .config.mak
@$(ECHO) "PRO_DIR ="$(PRO_DIR) >> .config.mak
@$(ECHO) "export PRO_DIR" >> .config.mak
+ @$(ECHO) "BRANCH ="$(BRANCH) >> .config.mak
+ @$(ECHO) "export BRANCH" >> .config.mak
+ @$(ECHO) "COMMIT ="$(COMMIT) >> .config.mak
+ @$(ECHO) "export COMMIT" >> .config.mak
@$(ECHO) "" >> .config.mak
@$(ECHO) "# profile" >> .config.mak
@$(ECHO) "PROF ="$(PROF) >> .config.mak
@@ -459,6 +474,10 @@ config : .null
@$(ECHO) "export MIPS" >> .config.mak
@$(ECHO) "export SPARC" >> .config.mak
@$(ECHO) "" >> .config.mak
+ @$(ECHO) "# backend" >> .config.mak
+ @$(ECHO) "RUNTIME ="$(RUNTIME) >> .config.mak
+ @$(ECHO) "export RUNTIME" >> .config.mak
+ @$(ECHO) "" >> .config.mak
@$(ECHO) "# demo" >> .config.mak
@$(ECHO) "DEMO ="$(DEMO) >> .config.mak
@$(ECHO) "export DEMO" >> .config.mak
diff --git a/core/project.mak b/core/project.mak
index eafef391e..3e3838897 100644
--- a/core/project.mak
+++ b/core/project.mak
@@ -7,14 +7,14 @@ PRO_NAME = xmake
PRO_VERSION_MAJOR = 2
# the project minor version
-PRO_VERSION_MINOR = 5
+PRO_VERSION_MINOR = 6
# the project alter version
-PRO_VERSION_ALTER = 6
+PRO_VERSION_ALTER = 2
# the project prefix
PRO_PREFIX = XM_
# the package names
-PKG_NAMES = tbox luajit base
+PKG_NAMES = tbox luajit lua base
diff --git a/core/src/demo/makefile b/core/src/demo/makefile
index 1a2142db5..6c4aad363 100644
--- a/core/src/demo/makefile
+++ b/core/src/demo/makefile
@@ -20,10 +20,20 @@ demo_INC_DIRS += ../ ../tbox/tbox/src ../tbox/inc/$(PLAT)
demo_LIB_DIRS += ../tbox
# luajit
+ifeq ($(RUNTIME),luajit)
luajit_LIBS := $(if $(findstring luajit,$(base_LIBNAMES)),,luajit$(DTYPE))
demo_LIBS += $(luajit_LIBS)
demo_INC_DIRS += ../luajit/luajit/src
demo_LIB_DIRS += ../luajit
+endif
+
+# lua
+ifeq ($(RUNTIME),lua)
+lua_LIBS := $(if $(findstring lua,$(base_LIBNAMES)),,lua$(DTYPE))
+demo_LIBS += $(lua_LIBS)
+demo_INC_DIRS += ../lua/lua
+demo_LIB_DIRS += ../lua
+endif
# sv
sv_DTYPE := $(if $(findstring sv,$(base_LIBNAMES)),,$(DTYPE))
diff --git a/core/src/demo/xmake.rc b/core/src/demo/xmake.rc
index 0d737ebc3..2167c8f25 100644
--- a/core/src/demo/xmake.rc
+++ b/core/src/demo/xmake.rc
@@ -26,7 +26,7 @@ BEGIN
VALUE "FileDescription", "XMake build utility"
VALUE "FileVersion", XM_CONFIG_VERSION "+" STR(XM_CONFIG_VERSION_BUILD)
VALUE "InternalName", "xmake"
- VALUE "LegalCopyright", "Copyright (C) 2015-2020 Ruki Wang, tboox.org, xmake.io\nCopyright (C) 2005-2015 Mike Pall, luajit.org"
+ VALUE "LegalCopyright", "Copyright (C) 2015-present Ruki Wang, tboox.org, xmake.io"
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "xmake.exe"
VALUE "ProductName", "XMake"
diff --git a/core/src/lcurses/lcurses.c b/core/src/lcurses/lcurses.c
index 934dc2d1d..6e7758ccf 100644
--- a/core/src/lcurses/lcurses.c
+++ b/core/src/lcurses/lcurses.c
@@ -65,9 +65,15 @@ Notes:
#include <stdlib.h>
#include <string.h>
+#ifdef USE_LUAJIT
#include "luajit.h"
#include "lualib.h"
#include "lauxlib.h"
+#else
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+#endif
#include <curses.h>
#include <signal.h>
@@ -330,7 +336,11 @@ static chtype lc_checkch(lua_State *L, int index)
if (lua_type(L, index) == LUA_TSTRING)
return *lua_tostring(L, index);
+#ifdef USE_LUAJIT
luaL_typerror(L, index, "chtype");
+#else
+ // TODO
+#endif
/* never executes */
return (chtype)0;
}
@@ -599,6 +609,12 @@ static void register_curses_constants(lua_State *L)
CC(KEY_COPY) CC(KEY_CREATE) CC(KEY_END)
CC(KEY_EXIT) CC(KEY_FIND) CC(KEY_HELP)
CC(KEY_MARK) CC(KEY_MESSAGE)
+#ifdef PDCURSES
+ // https://github.com/xmake-io/xmake/issues/1610#issuecomment-971149885
+ CC(KEY_C2) CC(KEY_A2) CC(KEY_B1)
+ CC(KEY_B3)
+#endif
+
#if !defined(XCURSES)
#ifndef NOMOUSE
CC(KEY_MOUSE)
@@ -2421,8 +2437,11 @@ int xm_curses_register (lua_State *L)
lua_pushliteral(L, "__index");
lua_pushvalue(L, -2); /* push metatable */
lua_rawset(L, -3); /* metatable.__index = metatable */
+#if 0
luaL_openlib(L, NULL, windowlib, 0);
-
+#else
+ luaL_setfuncs(L, windowlib, 0);
+#endif
lua_pop(L, 1); /* remove metatable from stack */
/*
@@ -2432,8 +2451,11 @@ int xm_curses_register (lua_State *L)
lua_pushliteral(L, "__index");
lua_pushvalue(L, -2); /* push metatable */
lua_rawset(L, -3); /* metatable.__index = metatable */
+#if 0
luaL_openlib(L, NULL, chstrlib, 0);
-
+#else
+ luaL_setfuncs(L, chstrlib, 0);
+#endif
lua_pop(L, 1); /* remove metatable from stack */
@@ -2441,7 +2463,11 @@ int xm_curses_register (lua_State *L)
** create global table with curses methods/variables/constants
*/
lua_newtable(L);
+#if 0
luaL_register(L, NULL, curseslib);
+#else
+ luaL_setfuncs(L, curseslib, 0);
+#endif
lua_pushstring(L, "init");
lua_pushvalue(L, -2);
diff --git a/core/src/lcurses/makefile b/core/src/lcurses/makefile
index 25752ab47..6347b4c8e 100644
--- a/core/src/lcurses/makefile
+++ b/core/src/lcurses/makefile
@@ -17,7 +17,14 @@ lcurses_C_FILES += lcurses
lcurses_CXFLAGS += $(if $(findstring curses,$(base_LIBNAMES)),-DXM_CONFIG_API_HAVE_CURSES,)
# includes
-lcurses_INC_DIRS += ../luajit/luajit/src
+ifeq ($(RUNTIME),luajit)
+lcurses_INC_DIRS += ../luajit/luajit/src
+lcurses_CXFLAGS += -DUSE_LUAJIT
+endif
+ifeq ($(RUNTIME),lua)
+lcurses_INC_DIRS += ../lua/lua
+lcurses_CXFLAGS += -DLUA_COMPAT_5_1 -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_3
+endif
# suffix
include $(PRO_DIR)/suffix.mak
diff --git a/core/src/lcurses/xmake.lua b/core/src/lcurses/xmake.lua
index f80117f10..d01058c56 100644
--- a/core/src/lcurses/xmake.lua
+++ b/core/src/lcurses/xmake.lua
@@ -1,6 +1,6 @@
target("lcurses")
set_kind("static")
- add_deps("luajit")
+ add_deps(get_config("runtime"))
if is_plat("windows") and has_config("pdcurses") then
add_deps("pdcurses")
add_defines("XM_CONFIG_API_HAVE_CURSES", {public = true})
diff --git a/core/src/lua-cjson/makefile b/core/src/lua-cjson/makefile
index 9e96851ae..4a2c4ffeb 100644
--- a/core/src/lua-cjson/makefile
+++ b/core/src/lua-cjson/makefile
@@ -22,8 +22,14 @@ lua-cjson_C_FILES += \
lua-cjson_CFLAGS += -DNDEBUG -DUSE_INTERNAL_FPCONV
# includes
-lua-cjson_INC_DIRS += \
- ../luajit/luajit/src
+ifeq ($(RUNTIME),luajit)
+lua-cjson_INC_DIRS += ../luajit/luajit/src
+lua-cjson_CXFLAGS += -DUSE_LUAJIT
+endif
+ifeq ($(RUNTIME),lua)
+lua-cjson_INC_DIRS += ../lua/lua
+lua-cjson_CXFLAGS += -DLUA_COMPAT_5_1 -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_3
+endif
# use given system library?
lua-cjson_C_FILES := $(if $(findstring cjson,$(base_LIBNAMES)),,$(lua-cjson_C_FILES))
diff --git a/core/src/lua-cjson/xmake.lua b/core/src/lua-cjson/xmake.lua
index d2eec99f0..75b62c16b 100644
--- a/core/src/lua-cjson/xmake.lua
+++ b/core/src/lua-cjson/xmake.lua
@@ -1,7 +1,7 @@
target("lua-cjson")
set_kind("static")
set_warnings("all")
- add_deps("luajit")
+ add_deps(get_config("runtime"))
if is_plat("windows") then
set_languages("c89")
end
diff --git a/core/src/lua/lua b/core/src/lua/lua
new file mode 160000
+Subproject eadd8c7178c79c814ecca9652973a9b9dd4cc71
diff --git a/core/src/lua/makefile b/core/src/lua/makefile
new file mode 100644
index 000000000..9db0fa518
--- /dev/null
+++ b/core/src/lua/makefile
@@ -0,0 +1,87 @@
+# prefix
+include $(PRO_DIR)/prefix.mak
+
+# module name
+NAMES = lua
+
+# module type
+lua_TYPE = LIB
+
+# config
+lua_CONFIG = n
+
+# core files
+lua_C_FILES += \
+ lua/lauxlib \
+ lua/liolib \
+ lua/lopcodes \
+ lua/lstate \
+ lua/lobject \
+ lua/lmathlib \
+ lua/loadlib \
+ lua/lvm \
+ lua/lfunc \
+ lua/lstrlib \
+ lua/linit \
+ lua/lstring \
+ lua/lundump \
+ lua/lctype \
+ lua/ltable \
+ lua/ldump \
+ lua/loslib \
+ lua/lgc \
+ lua/lzio \
+ lua/ldblib \
+ lua/lutf8lib \
+ lua/lmem \
+ lua/lcorolib \
+ lua/lcode \
+ lua/ltablib \
+ lua/lapi \
+ lua/lbaselib \
+ lua/ldebug \
+ lua/lparser \
+ lua/llex \
+ lua/ltm \
+ lua/ltests \
+ lua/ldo
+
+# is windows?
+iswin =
+ifeq ($(PLAT),windows)
+ iswin = yes
+endif
+ifeq ($(PLAT),msys)
+ iswin = yes
+endif
+ifeq ($(PLAT),mingw)
+ iswin = yes
+endif
+ifeq ($(PLAT),cygwin)
+ iswin = yes
+endif
+
+lua_CFLAGS := -std=c99 -DLUA_COMPAT_5_1 -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_3
+ifdef iswin
+lua_CFLAGS_PLAT := -DLUA_USE_WINDOWS
+endif
+
+ifeq ($(PLAT),macosx)
+lua_CFLAGS += -Wno-error=string-plus-int
+lua_CFLAGS_PLAT := -DLUA_USE_MACOSX
+endif
+
+ifeq ($(lua_CFLAGS_PLAT),)
+lua_CFLAGS_PLAT := -DLUA_USE_LINUX
+endif
+lua_CFLAGS += $(lua_CFLAGS_PLAT)
+
+# use given system library?
+lua_C_FILES := $(if $(findstring lua,$(base_LIBNAMES)),,$(lua_C_FILES))
+lua_ASM_FILES := $(if $(findstring lua,$(base_LIBNAMES)),,$(lua_ASM_FILES))
+lua_INC_FILES := $(if $(findstring lua,$(base_LIBNAMES)),,$(lua_INC_FILES))
+lua_OBJ_FILES := $(if $(findstring lua,$(base_LIBNAMES)),,$(lua_OBJ_FILES))
+
+# suffix
+include $(PRO_DIR)/suffix.mak
+
diff --git a/core/src/lua/xmake.lua b/core/src/lua/xmake.lua
new file mode 100644
index 000000000..379bdc46a
--- /dev/null
+++ b/core/src/lua/xmake.lua
@@ -0,0 +1,31 @@
+target("lua")
+ if not is_config("runtime", "lua") then
+ set_default(false)
+ end
+ set_kind("static")
+ set_warnings("all")
+
+ -- disable c99(/TP) for windows
+ if is_plat("windows") then
+ set_languages("c89")
+ end
+
+ -- add header files
+ add_headerfiles("lua/(*.h)", {prefixdir = "lua"})
+
+ -- add include directories
+ add_includedirs("lua", {public = true})
+
+ -- add the common source files
+ add_files("lua/*.c|lua.c|onelua.c")
+
+ -- add defines
+ add_defines("LUA_COMPAT_5_1", "LUA_COMPAT_5_2", "LUA_COMPAT_5_3", {public = true})
+ if is_plat("windows") then
+ add_defines("LUA_USE_WINDOWS")
+ elseif is_plat("macosx", "iphoneos") then
+ add_defines("LUA_USE_MACOSX")
+ else
+ add_defines("LUA_USE_LINUX")
+ end
+
diff --git a/core/src/luajit/xmake.lua b/core/src/luajit/xmake.lua
index cfee1f76e..a3c7120df 100644
--- a/core/src/luajit/xmake.lua
+++ b/core/src/luajit/xmake.lua
@@ -23,6 +23,9 @@ local autogendir = path.join("autogen", plat, jit and "jit" or "nojit", arch)
-- add target
target("luajit")
+ if not is_config("runtime", "luajit") then
+ set_default(false)
+ end
-- make as a static library
set_kind("static")
@@ -52,6 +55,8 @@ target("luajit")
add_files(autogendir .. "/*.S")
end
+ add_defines("USE_LUAJIT", {interface = true})
+
-- disable jit compiler?
if not jit then
add_defines("LUAJIT_DISABLE_JIT")
diff --git a/core/src/makefile b/core/src/makefile
index 21a06ed5a..f16a1557d 100644
--- a/core/src/makefile
+++ b/core/src/makefile
@@ -2,8 +2,14 @@
include $(PRO_DIR)/prefix.mak
# projects
-SUB_PROS += demo
-DEP_PROS += lcurses sv luajit lua-cjson tbox xmake
+SUB_PROS += demo
+ifeq ($(RUNTIME),luajit)
+DEP_PROS += luajit
+endif
+ifeq ($(RUNTIME),lua)
+DEP_PROS += lua
+endif
+DEP_PROS += lcurses sv lua-cjson tbox xmake
# suffix
include $(PRO_DIR)/suffix.mak
diff --git a/core/src/sv/sv b/core/src/sv/sv
-Subproject 9a3cf7c8e589de4f70378824329882c4a047fff
+Subproject 035262773da0500367cb88e6f30197908159a34
diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox
-Subproject 5ef932750ede0b90867fd4afdcf1deed2464c82
+Subproject 122a479e626ee3fdd7d6c1117ec7c19212a1e08
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index 6a401a486..e87fce465 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -187,6 +187,7 @@ tb_int_t xm_winos_logical_drives(lua_State* lua);
tb_int_t xm_winos_registry_query(lua_State* lua);
tb_int_t xm_winos_registry_keys(lua_State* lua);
tb_int_t xm_winos_registry_values(lua_State* lua);
+tb_int_t xm_winos_short_path(lua_State* lua);
#endif
// the string functions
@@ -221,6 +222,19 @@ tb_int_t xm_semver_compare(lua_State* lua);
tb_int_t xm_semver_satisfies(lua_State* lua);
tb_int_t xm_semver_select(lua_State* lua);
+// the libc functions
+tb_int_t xm_libc_malloc(lua_State* lua);
+tb_int_t xm_libc_free(lua_State* lua);
+tb_int_t xm_libc_memcpy(lua_State* lua);
+tb_int_t xm_libc_memset(lua_State* lua);
+tb_int_t xm_libc_strndup(lua_State* lua);
+tb_int_t xm_libc_dataptr(lua_State* lua);
+tb_int_t xm_libc_byteof(lua_State* lua);
+tb_int_t xm_libc_setbyte(lua_State* lua);
+
+// the tty functions
+tb_int_t xm_tty_term_mode(lua_State* lua);
+
#ifdef XM_CONFIG_API_HAVE_CURSES
// register curses
__tb_extern_c_enter__
@@ -291,6 +305,7 @@ static luaL_Reg const g_winos_functions[] =
, { "registry_query", xm_winos_registry_query }
, { "registry_keys", xm_winos_registry_keys }
, { "registry_values", xm_winos_registry_values }
+, { "short_path", xm_winos_short_path }
, { tb_null, tb_null }
};
#endif
@@ -412,6 +427,27 @@ static luaL_Reg const g_semver_functions[] =
, { tb_null, tb_null }
};
+// the libc functions
+static luaL_Reg const g_libc_functions[] =
+{
+ { "malloc", xm_libc_malloc }
+, { "free", xm_libc_free }
+, { "memcpy", xm_libc_memcpy }
+, { "memset", xm_libc_memset }
+, { "strndup", xm_libc_strndup }
+, { "dataptr", xm_libc_dataptr }
+, { "byteof", xm_libc_byteof }
+, { "setbyte", xm_libc_setbyte }
+, { tb_null, tb_null }
+};
+
+// the tty functions
+static luaL_Reg const g_tty_functions[] =
+{
+ { "term_mode", xm_tty_term_mode }
+, { tb_null, tb_null }
+};
+
/* //////////////////////////////////////////////////////////////////////////////////////
* private implementation
*/
@@ -586,7 +622,7 @@ static tb_bool_t xm_engine_get_program_directory(xm_engine_t* engine, tb_char_t*
tb_size_t i;
tb_file_info_t info;
tb_char_t scriptpath[TB_PATH_MAXN];
- tb_char_t const* subdirs[] = {"", sharedir};
+ tb_char_t const* subdirs[] = {".", sharedir};
for (i = 0; i < tb_arrayn(subdirs); i++)
{
// get program directory
@@ -814,45 +850,51 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c
tb_strlcpy(engine->name, name, sizeof(engine->name));
// init lua
- engine->lua = lua_open();
+ engine->lua = luaL_newstate();
tb_assert_and_check_break(engine->lua);
// open lua libraries
luaL_openlibs(engine->lua);
// bind os functions
- luaL_register(engine->lua, "os", g_os_functions);
+ xm_lua_register(engine->lua, "os", g_os_functions);
// bind io functions
- luaL_register(engine->lua, "io", g_io_functions);
+ xm_lua_register(engine->lua, "io", g_io_functions);
// bind path functions
- luaL_register(engine->lua, "path", g_path_functions);
+ xm_lua_register(engine->lua, "path", g_path_functions);
// bind hash functions
- luaL_register(engine->lua, "hash", g_hash_functions);
+ xm_lua_register(engine->lua, "hash", g_hash_functions);
// bind string functions
- luaL_register(engine->lua, "string", g_string_functions);
+ xm_lua_register(engine->lua, "string", g_string_functions);
// bind process functions
- luaL_register(engine->lua, "process", g_process_functions);
+ xm_lua_register(engine->lua, "process", g_process_functions);
// bind sandbox functions
- luaL_register(engine->lua, "sandbox", g_sandbox_functions);
+ xm_lua_register(engine->lua, "sandbox", g_sandbox_functions);
// bind windows functions
#ifdef TB_CONFIG_OS_WINDOWS
- luaL_register(engine->lua, "winos", g_winos_functions);
+ xm_lua_register(engine->lua, "winos", g_winos_functions);
#endif
#ifdef XM_CONFIG_API_HAVE_READLINE
// bind readline functions
- luaL_register(engine->lua, "readline", g_readline_functions);
+ xm_lua_register(engine->lua, "readline", g_readline_functions);
#endif
// bind semver functions
- luaL_register(engine->lua, "semver", g_semver_functions);
+ xm_lua_register(engine->lua, "semver", g_semver_functions);
+
+ // bind libc functions
+ xm_lua_register(engine->lua, "libc", g_libc_functions);
+
+ // bind tty functions
+ xm_lua_register(engine->lua, "tty", g_tty_functions);
#ifdef XM_CONFIG_API_HAVE_CURSES
// bind curses
@@ -879,7 +921,9 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c
// init version string
tb_char_t version_cstr[256] = {0};
- tb_snprintf(version_cstr, sizeof(version_cstr), "%u.%u.%u+%llu", version->major, version->minor, version->alter, version->build);
+ if (tb_strcmp(XM_CONFIG_VERSION_BRANCH, "") && tb_strcmp(XM_CONFIG_VERSION_COMMIT, ""))
+ tb_snprintf(version_cstr, sizeof(version_cstr), "%u.%u.%u+%s.%s", version->major, version->minor, version->alter, XM_CONFIG_VERSION_BRANCH, XM_CONFIG_VERSION_COMMIT);
+ else tb_snprintf(version_cstr, sizeof(version_cstr), "%u.%u.%u+%llu", version->major, version->minor, version->alter, version->build);
lua_pushstring(engine->lua, version_cstr);
lua_setglobal(engine->lua, "_VERSION");
@@ -892,6 +936,14 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c
lua_pushstring(engine->lua, name? name : "xmake");
lua_setglobal(engine->lua, "_NAME");
+ // use luajit as runtime?
+#ifdef USE_LUAJIT
+ lua_pushboolean(engine->lua, tb_true);
+#else
+ lua_pushboolean(engine->lua, tb_false);
+#endif
+ lua_setglobal(engine->lua, "_LUAJIT");
+
// init namespace: xmake
lua_newtable(engine->lua);
lua_setglobal(engine->lua, "xmake");
@@ -1024,7 +1076,7 @@ tb_void_t xm_engine_register(xm_engine_ref_t self, tb_char_t const* module, luaL
// do register
lua_pushstring(engine->lua, module);
lua_newtable(engine->lua);
- luaL_register(engine->lua, tb_null, funcs);
+ xm_lua_register(engine->lua, tb_null, funcs);
lua_rawset(engine->lua, -3);
}
tb_int_t xm_engine_run(tb_char_t const* name, tb_int_t argc, tb_char_t** argv, tb_char_t** taskargv, xm_engine_lni_initalizer_cb_t lni_initalizer)
diff --git a/core/src/xmake/io/file_open.c b/core/src/xmake/io/file_open.c
index c92380207..435e2aec0 100644
--- a/core/src/xmake/io/file_open.c
+++ b/core/src/xmake/io/file_open.c
@@ -231,6 +231,11 @@ tb_int_t xm_io_file_open(lua_State* lua)
else xm_io_return_error(lua, "invalid open mode!");
tb_assert_and_check_return_val(encoding != XM_IO_FILE_ENCODING_UNKNOWN, 0);
+ // write data with utf bom? e.g. utf8bom, utf16lebom, utf16bom
+ tb_bool_t utfbom = tb_false;
+ if (tb_strstr(modestr, "bom"))
+ utfbom = tb_true;
+
// open file
tb_bool_t open_ok = tb_false;
tb_stream_ref_t file_ref = tb_null;
@@ -293,6 +298,7 @@ tb_int_t xm_io_file_open(lua_State* lua)
file->mode = mode;
file->type = XM_IO_FILE_TYPE_FILE;
file->encoding = encoding;
+ file->utfbom = utfbom;
// init the read/write line cache buffer
tb_buffer_init(&file->rcache);
diff --git a/core/src/xmake/io/file_write.c b/core/src/xmake/io/file_write.c
index 12ab829b3..c7db01937 100644
--- a/core/src/xmake/io/file_write.c
+++ b/core/src/xmake/io/file_write.c
@@ -33,6 +33,36 @@
/* //////////////////////////////////////////////////////////////////////////////////////
* private implementation
*/
+static tb_void_t xm_io_file_write_file_utfbom(xm_io_file_t* file)
+{
+ // check
+ tb_assert(file && data && xm_io_file_is_file(file) && file->file_ref);
+
+ // write bom
+ switch (file->encoding)
+ {
+ case TB_CHARSET_TYPE_UTF8:
+ {
+ static tb_byte_t bom[] = {0xef, 0xbb, 0xbf};
+ tb_stream_bwrit(file->file_ref, bom, sizeof(bom));
+ }
+ break;
+ case TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_LE:
+ {
+ static tb_byte_t bom[] = {0xff, 0xfe};
+ tb_stream_bwrit(file->file_ref, bom, sizeof(bom));
+ }
+ break;
+ case TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_BE:
+ {
+ static tb_byte_t bom[] = {0xfe, 0xff};
+ tb_stream_bwrit(file->file_ref, bom, sizeof(bom));
+ }
+ break;
+ default:
+ break;
+ }
+}
static tb_void_t xm_io_file_write_file_directly(xm_io_file_t* file, tb_char_t const* data, tb_size_t size)
{
// check
@@ -141,7 +171,15 @@ tb_int_t xm_io_file_write(lua_State* lua)
else if (is_binary)
xm_io_file_write_file_directly(file, data, (tb_size_t)datasize);
else
+ {
+ // write utf bom first?
+ if (file->utfbom)
+ {
+ xm_io_file_write_file_utfbom(file);
+ file->utfbom = tb_false;
+ }
xm_io_file_write_file_transcrlf(file, data, (tb_size_t)datasize);
+ }
}
}
lua_settop(lua, 1);
diff --git a/core/src/xmake/io/pipe_read.c b/core/src/xmake/io/pipe_read.c
index 73451995b..72a931f5c 100644
--- a/core/src/xmake/io/pipe_read.c
+++ b/core/src/xmake/io/pipe_read.c
@@ -69,7 +69,7 @@ tb_int_t xm_io_pipe_read(lua_State* lua)
if (size <= 0)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid size(%ld)!", size);
+ lua_pushfstring(lua, "invalid size(%d)!", (tb_int_t)size);
return 2;
}
diff --git a/core/src/xmake/io/pipe_write.c b/core/src/xmake/io/pipe_write.c
index 27d805ace..c44836783 100644
--- a/core/src/xmake/io/pipe_write.c
+++ b/core/src/xmake/io/pipe_write.c
@@ -78,7 +78,7 @@ tb_int_t xm_io_pipe_write(lua_State* lua)
if (!data || !size)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid data(%p) and size(%zu)!", data, size);
+ lua_pushfstring(lua, "invalid data(%p) and size(%d)!", data, (tb_int_t)size);
return 2;
}
@@ -88,7 +88,7 @@ tb_int_t xm_io_pipe_write(lua_State* lua)
if (start < 1 || start > size)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid start position(%ld)!", start);
+ lua_pushfstring(lua, "invalid start position(%d)!", (tb_int_t)start);
return 2;
}
@@ -98,7 +98,7 @@ tb_int_t xm_io_pipe_write(lua_State* lua)
if (last < start - 1 || last > size + start - 1)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid last position(%ld)!", last);
+ lua_pushfstring(lua, "invalid last position(%d)!", (tb_int_t)last);
return 2;
}
diff --git a/core/src/xmake/io/prefix.h b/core/src/xmake/io/prefix.h
index e11198da1..bec186a92 100644
--- a/core/src/xmake/io/prefix.h
+++ b/core/src/xmake/io/prefix.h
@@ -88,6 +88,7 @@ typedef struct __xm_io_file_t
tb_size_t mode; // tb_file_mode_t
tb_size_t type; // xm_io_file_type_e
tb_size_t encoding; // value of xm_io_file_encoding_e or tb_charset_type_e
+ tb_bool_t utfbom; // write utf-bom for utf encoding?
tb_buffer_t rcache; // the read line cache buffer
tb_buffer_t wcache; // the write line cache buffer
diff --git a/core/src/xmake/io/socket_recv.c b/core/src/xmake/io/socket_recv.c
index aefdfc485..e3bd2dfed 100644
--- a/core/src/xmake/io/socket_recv.c
+++ b/core/src/xmake/io/socket_recv.c
@@ -69,7 +69,7 @@ tb_int_t xm_io_socket_recv(lua_State* lua)
if (size <= 0)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid size(%ld)!", size);
+ lua_pushfstring(lua, "invalid size(%d)!", (tb_int_t)size);
return 2;
}
diff --git a/core/src/xmake/io/socket_recvfrom.c b/core/src/xmake/io/socket_recvfrom.c
index 243e6e08f..2a6ed7a16 100644
--- a/core/src/xmake/io/socket_recvfrom.c
+++ b/core/src/xmake/io/socket_recvfrom.c
@@ -69,7 +69,7 @@ tb_int_t xm_io_socket_recvfrom(lua_State* lua)
if (size <= 0)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid size(%ld)!", size);
+ lua_pushfstring(lua, "invalid size(%d)!", (tb_int_t)size);
return 2;
}
diff --git a/core/src/xmake/io/socket_send.c b/core/src/xmake/io/socket_send.c
index 71c057de8..5d697f3e4 100644
--- a/core/src/xmake/io/socket_send.c
+++ b/core/src/xmake/io/socket_send.c
@@ -78,7 +78,7 @@ tb_int_t xm_io_socket_send(lua_State* lua)
if (!data || !size)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid data(%p) and size(%zu)!", data, size);
+ lua_pushfstring(lua, "invalid data(%p) and size(%d)!", data, (tb_int_t)size);
return 2;
}
@@ -88,7 +88,7 @@ tb_int_t xm_io_socket_send(lua_State* lua)
if (start < 1 || start > size)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid start position(%ld)!", start);
+ lua_pushfstring(lua, "invalid start position(%d)!", (tb_int_t)start);
return 2;
}
@@ -98,7 +98,7 @@ tb_int_t xm_io_socket_send(lua_State* lua)
if (last < start - 1 || last > size + start - 1)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid last position(%ld)!", last);
+ lua_pushfstring(lua, "invalid last position(%d)!", (tb_int_t)last);
return 2;
}
diff --git a/core/src/xmake/io/socket_sendfile.c b/core/src/xmake/io/socket_sendfile.c
index fba10874b..456d23b49 100644
--- a/core/src/xmake/io/socket_sendfile.c
+++ b/core/src/xmake/io/socket_sendfile.c
@@ -96,7 +96,7 @@ tb_int_t xm_io_socket_sendfile(lua_State* lua)
if (start < 1 || start > filesize)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid start position(%ld)!", start);
+ lua_pushfstring(lua, "invalid start position(%d)!", (tb_int_t)start);
return 2;
}
@@ -106,7 +106,7 @@ tb_int_t xm_io_socket_sendfile(lua_State* lua)
if (last < start - 1 || last > filesize + start - 1)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid last position(%ld)!", last);
+ lua_pushfstring(lua, "invalid last position(%d)!", (tb_int_t)last);
return 2;
}
diff --git a/core/src/xmake/io/socket_sendto.c b/core/src/xmake/io/socket_sendto.c
index 864b51936..f203df5b6 100644
--- a/core/src/xmake/io/socket_sendto.c
+++ b/core/src/xmake/io/socket_sendto.c
@@ -78,7 +78,7 @@ tb_int_t xm_io_socket_sendto(lua_State* lua)
if (!data || !size)
{
lua_pushinteger(lua, -1);
- lua_pushfstring(lua, "invalid data(%p) and size(%zu)!", data, size);
+ lua_pushfstring(lua, "invalid data(%p) and size(%d)!", data, (tb_int_t)size);
return 2;
}
diff --git a/core/src/xmake/io/stdfile.c b/core/src/xmake/io/stdfile.c
index 67823cf3e..1daf7c794 100644
--- a/core/src/xmake/io/stdfile.c
+++ b/core/src/xmake/io/stdfile.c
@@ -120,7 +120,7 @@ tb_int_t xm_io_stdfile(lua_State* lua)
tb_assert_and_check_return_val(lua, 0);
// get std type
- tb_long_t type = lua_tointeger(lua, 1);
+ tb_long_t type = (tb_long_t)lua_tointeger(lua, 1);
/* push a new stdfile
*
diff --git a/core/src/xmake/libc/byteof.c b/core/src/xmake/libc/byteof.c
new file mode 100644
index 000000000..b6d757c81
--- /dev/null
+++ b/core/src/xmake/libc/byteof.c
@@ -0,0 +1,58 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file byteof.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "byteof"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_byteof(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get data
+ tb_pointer_t data = tb_null;
+ if (lua_isnumber(lua, 1))
+ data = (tb_pointer_t)(tb_size_t)lua_tointeger(lua, 1);
+ else if (lua_isstring(lua, 1))
+ data = (tb_pointer_t)luaL_checkstring(lua, 1);
+ else xm_libc_return_error(lua, "libc.byteof(invalid data)!");
+
+ // get offset
+ tb_int_t offset = 0;
+ if (lua_isnumber(lua, 2))
+ offset = (tb_int_t)lua_tointeger(lua, 2);
+ else xm_libc_return_error(lua, "libc.byteof(invalid offset)!");
+ lua_pushinteger(lua, ((tb_byte_t const*)data)[offset]);
+ return 1;
+}
+
+
diff --git a/core/src/xmake/libc/dataptr.c b/core/src/xmake/libc/dataptr.c
new file mode 100644
index 000000000..d8d6c6f0d
--- /dev/null
+++ b/core/src/xmake/libc/dataptr.c
@@ -0,0 +1,52 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file dataptr.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "dataptr"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_dataptr(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ tb_pointer_t data = tb_null;
+ if (lua_isstring(lua, 1))
+ data = (tb_pointer_t)luaL_checkstring(lua, 1);
+ else if (lua_isnumber(lua, 1))
+ data = (tb_pointer_t)(tb_size_t)lua_tointeger(lua, 1);
+ else if (xm_lua_ispointer(lua, 1))
+ data = (tb_pointer_t)xm_lua_topointer(lua, 1);
+ else xm_libc_return_error(lua, "libc.dataptr(invalid data)!");
+ lua_pushinteger(lua, (lua_Integer)data);
+ return 1;
+}
+
diff --git a/core/src/xmake/libc/free.c b/core/src/xmake/libc/free.c
new file mode 100644
index 000000000..4fa549975
--- /dev/null
+++ b/core/src/xmake/libc/free.c
@@ -0,0 +1,46 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file free.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "free"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_free(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // do free
+ tb_pointer_t data = (tb_pointer_t)(tb_size_t)luaL_checkinteger(lua, 1);
+ if (data) tb_free(data);
+ return 0;
+}
+
diff --git a/core/src/xmake/libc/malloc.c b/core/src/xmake/libc/malloc.c
new file mode 100644
index 000000000..ae13547a3
--- /dev/null
+++ b/core/src/xmake/libc/malloc.c
@@ -0,0 +1,48 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file malloc.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "malloc"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_malloc(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // do malloc
+ tb_pointer_t data = tb_null;
+ tb_long_t size = (tb_long_t)luaL_checkinteger(lua, 1);
+ if (size > 0) data = tb_malloc(size);
+ lua_pushinteger(lua, (lua_Integer)data);
+ return 1;
+}
+
diff --git a/core/src/xmake/libc/memcpy.c b/core/src/xmake/libc/memcpy.c
new file mode 100644
index 000000000..3f8d3b36e
--- /dev/null
+++ b/core/src/xmake/libc/memcpy.c
@@ -0,0 +1,49 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file memcpy.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "memcpy"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_memcpy(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // do memcpy
+ tb_pointer_t dst = (tb_pointer_t)(tb_size_t)luaL_checkinteger(lua, 1);
+ tb_pointer_t src = (tb_pointer_t)(tb_size_t)luaL_checkinteger(lua, 2);
+ tb_int_t size = (tb_int_t)lua_tointeger(lua, 3);
+ if (dst && src && size > 0)
+ tb_memcpy(dst, src, size);
+ return 0;
+}
+
diff --git a/core/src/xmake/libc/memset.c b/core/src/xmake/libc/memset.c
new file mode 100644
index 000000000..5aef08105
--- /dev/null
+++ b/core/src/xmake/libc/memset.c
@@ -0,0 +1,49 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file memset.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "memset"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_memset(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // do memset
+ tb_pointer_t data = (tb_pointer_t)(tb_size_t)luaL_checkinteger(lua, 1);
+ tb_char_t ch = (tb_char_t)lua_tointeger(lua, 2);
+ tb_int_t size = (tb_int_t)lua_tointeger(lua, 3);
+ if (data && size > 0)
+ tb_memset(data, ch, size);
+ return 0;
+}
+
diff --git a/core/src/xmake/libc/prefix.h b/core/src/xmake/libc/prefix.h
new file mode 100644
index 000000000..a220690d6
--- /dev/null
+++ b/core/src/xmake/libc/prefix.h
@@ -0,0 +1,44 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file prefix.h
+ *
+ */
+#ifndef XM_LIBC_PREFIX_H
+#define XM_LIBC_PREFIX_H
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "../prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * macros
+ */
+
+// return libc error
+#define xm_libc_return_error(lua, error) \
+ do \
+ { \
+ lua_pushnil(lua); \
+ lua_pushliteral(lua, error); \
+ return 2; \
+ } while (0)
+
+#endif
+
+
diff --git a/core/src/xmake/libc/setbyte.c b/core/src/xmake/libc/setbyte.c
new file mode 100644
index 000000000..5027411a8
--- /dev/null
+++ b/core/src/xmake/libc/setbyte.c
@@ -0,0 +1,62 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file setbyte.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "setbyte"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_setbyte(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get data
+ tb_pointer_t data = tb_null;
+ if (lua_isnumber(lua, 1))
+ data = (tb_pointer_t)(tb_size_t)lua_tointeger(lua, 1);
+ else if (lua_isstring(lua, 1))
+ data = (tb_pointer_t)luaL_checkstring(lua, 1);
+ else xm_libc_return_error(lua, "libc.setbyte(invalid data)!");
+
+ // get offset
+ tb_int_t offset = 0;
+ if (lua_isnumber(lua, 2))
+ offset = (tb_int_t)lua_tointeger(lua, 2);
+ else xm_libc_return_error(lua, "libc.setbyte(invalid offset)!");
+
+ // set byte
+ if (lua_isnumber(lua, 3))
+ ((tb_byte_t*)data)[offset] = (tb_byte_t)lua_tointeger(lua, 3);
+ else xm_libc_return_error(lua, "libc.setbyte(invalid value)!");
+ return 0;
+}
+
+
diff --git a/core/src/xmake/libc/strndup.c b/core/src/xmake/libc/strndup.c
new file mode 100644
index 000000000..b56a76714
--- /dev/null
+++ b/core/src/xmake/libc/strndup.c
@@ -0,0 +1,54 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file strndup.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "strndup"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_libc_strndup(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // do strndup
+ tb_char_t const* s = tb_null;
+ if (lua_isnumber(lua, 1))
+ s = (tb_char_t const*)(tb_size_t)lua_tointeger(lua, 1);
+ else if (lua_isstring(lua, 2))
+ s = lua_tostring(lua, 2);
+ else xm_libc_return_error(lua, "libc.strndup(invalid args)!");
+ tb_int_t n = (tb_int_t)lua_tointeger(lua, 2);
+ if (s && n >= 0)
+ lua_pushlstring(lua, s, n);
+ else lua_pushliteral(lua, "");
+ return 1;
+}
+
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 2c45588b4..c85696f1e 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -115,7 +115,16 @@ xmake_C_FILES += \
readline/readline \
readline/history_list \
readline/add_history \
- readline/clear_history
+ readline/clear_history \
+ libc/malloc \
+ libc/free \
+ libc/memset \
+ libc/memcpy \
+ libc/dataptr \
+ libc/byteof \
+ libc/setbyte \
+ libc/strndup \
+ tty/term_mode
iswin =
ifeq ($(PLAT),windows)
@@ -137,7 +146,8 @@ xmake_C_FILES += \
winos/logical_drives \
winos/registry_keys \
winos/registry_values \
- winos/registry_query
+ winos/registry_query \
+ winos/short_path
endif
# flags
@@ -149,9 +159,17 @@ xmake_CXFLAGS += $(if $(findstring curses,$(base_LIBNAMES)),-DXM_CONFIG
xmake_INC_DIRS += \
../tbox/tbox/src \
../tbox/inc/$(PLAT) \
- ../luajit/luajit/src \
../sv/sv/include
-
+ifeq ($(RUNTIME),luajit)
+xmake_INC_DIRS += ../luajit/luajit/src
+xmake_CXFLAGS += -DUSE_LUAJIT
+endif
+ifeq ($(RUNTIME),lua)
+xmake_INC_DIRS += ../lua/lua
+xmake_CXFLAGS += -DLUA_COMPAT_5_1 -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_3
+endif
+xmake_CXFLAGS += -DXM_CONFIG_VERSION_BRANCH="\"$(BRANCH)\""
+xmake_CXFLAGS += -DXM_CONFIG_VERSION_COMMIT="\"$(COMMIT)\""
# suffix
include $(PRO_DIR)/suffix.mak
diff --git a/core/src/xmake/os/args.c b/core/src/xmake/os/args.c
index 4f1c89f7f..c6de9e6c6 100644
--- a/core/src/xmake/os/args.c
+++ b/core/src/xmake/os/args.c
@@ -108,7 +108,7 @@ tb_int_t xm_os_args(lua_State* lua)
if (lua_istable(lua, 1))
{
tb_size_t i = 0;
- tb_size_t n = lua_objlen(lua, 1);
+ tb_size_t n = (tb_size_t)lua_objlen(lua, 1);
for (i = 1; i <= n; i++)
{
// add space
diff --git a/core/src/xmake/os/find.c b/core/src/xmake/os/find.c
index 9d6a17eff..28539a138 100644
--- a/core/src/xmake/os/find.c
+++ b/core/src/xmake/os/find.c
@@ -177,10 +177,10 @@ tb_int_t xm_os_find(lua_State* lua)
tb_check_return_val(pattern, 0);
// the recursion level
- tb_long_t recursion = lua_tointeger(lua, 3);
+ tb_long_t recursion = (tb_long_t)lua_tointeger(lua, 3);
// the match mode
- tb_long_t mode = lua_tointeger(lua, 4);
+ tb_long_t mode = (tb_long_t)lua_tointeger(lua, 4);
// init table
lua_newtable(lua);
diff --git a/core/src/xmake/prefix.h b/core/src/xmake/prefix.h
index f1287b5c9..fabb775fb 100644
--- a/core/src/xmake/prefix.h
+++ b/core/src/xmake/prefix.h
@@ -32,9 +32,15 @@
# define LUA_API extern "C"
# define LUALIB_API LUA_API
#endif
-#include "luajit.h"
-#include "lualib.h"
-#include "lauxlib.h"
+#ifdef USE_LUAJIT
+# include "luajit.h"
+# include "lualib.h"
+# include "lauxlib.h"
+#else
+# include "lua.h"
+# include "lualib.h"
+# include "lauxlib.h"
+#endif
/* //////////////////////////////////////////////////////////////////////////////////////
* private interfaces
@@ -108,6 +114,22 @@ static __tb_inline__ tb_pointer_t xm_lua_topointer(lua_State* lua, tb_int_t idx)
}
#endif
+static __tb_inline__ tb_void_t xm_lua_register(lua_State *lua, tb_char_t const* libname, luaL_Reg const* l)
+{
+#if LUA_VERSION_NUM >= 504
+ lua_getglobal(lua, libname);
+ if (lua_isnil(lua, -1))
+ {
+ lua_pop(lua, 1);
+ lua_newtable(lua);
+ }
+ luaL_setfuncs(lua, l, 0);
+ lua_setglobal(lua, libname);
+#else
+ luaL_register(lua, libname, l);
+#endif
+}
+
#endif
diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c
index 82ea5b94f..083a01070 100644
--- a/core/src/xmake/process/open.c
+++ b/core/src/xmake/process/open.c
@@ -56,7 +56,7 @@ tb_int_t xm_process_open(lua_State* lua)
// get option arguments
tb_size_t envn = 0;
- tb_char_t const* envs[256] = {0};
+ tb_char_t const* envs[1024] = {0};
tb_char_t const* inpath = tb_null;
tb_char_t const* outpath = tb_null;
tb_char_t const* errpath = tb_null;
@@ -178,14 +178,14 @@ tb_int_t xm_process_open(lua_State* lua)
else
{
// error
- lua_pushfstring(lua, "envs is too large(%lu > %d) for process.openv", envn, tb_arrayn(envs) - 1);
+ lua_pushfstring(lua, "envs is too large(%d > %d) for process.openv", (tb_int_t)envn, tb_arrayn(envs) - 1);
lua_error(lua);
}
}
else
{
// error
- lua_pushfstring(lua, "invalid envs[%ld] type(%s) for process.openv", i, luaL_typename(lua, -1));
+ lua_pushfstring(lua, "invalid envs[%d] type(%s) for process.openv", (tb_int_t)i, luaL_typename(lua, -1));
lua_error(lua);
}
diff --git a/core/src/xmake/process/openv.c b/core/src/xmake/process/openv.c
index 02ccb49e7..493ba02ec 100644
--- a/core/src/xmake/process/openv.c
+++ b/core/src/xmake/process/openv.c
@@ -60,7 +60,7 @@ tb_int_t xm_process_openv(lua_State* lua)
tb_check_return_val(shellname, 0);
// get the arguments count
- tb_long_t argn = lua_objlen(lua, 2);
+ tb_long_t argn = (tb_long_t)lua_objlen(lua, 2);
tb_check_return_val(argn >= 0, 0);
// get arguments
@@ -85,7 +85,7 @@ tb_int_t xm_process_openv(lua_State* lua)
else
{
// error
- lua_pushfstring(lua, "invalid argv[%ld] type(%s) for process.openv", argi, luaL_typename(lua, -1));
+ lua_pushfstring(lua, "invalid argv[%d] type(%s) for process.openv", (tb_int_t)argi, luaL_typename(lua, -1));
lua_error(lua);
}
@@ -98,7 +98,7 @@ tb_int_t xm_process_openv(lua_State* lua)
// get option arguments
tb_size_t envn = 0;
- tb_char_t const* envs[256] = {0};
+ tb_char_t const* envs[1024] = {0};
tb_char_t const* inpath = tb_null;
tb_char_t const* outpath = tb_null;
tb_char_t const* errpath = tb_null;
@@ -220,14 +220,14 @@ tb_int_t xm_process_openv(lua_State* lua)
else
{
// error
- lua_pushfstring(lua, "envs is too large(%lu > %d) for process.openv", envn, tb_arrayn(envs) - 1);
+ lua_pushfstring(lua, "envs is too large(%d > %d) for process.openv", (tb_int_t)envn, tb_arrayn(envs) - 1);
lua_error(lua);
}
}
else
{
// error
- lua_pushfstring(lua, "invalid envs[%ld] type(%s) for process.openv", i, luaL_typename(lua, -1));
+ lua_pushfstring(lua, "invalid envs[%d] type(%s) for process.openv", (tb_int_t)i, luaL_typename(lua, -1));
lua_error(lua);
}
diff --git a/core/src/xmake/sandbox/interactive.c b/core/src/xmake/sandbox/interactive.c
index 2519a58e8..fc0acad12 100644
--- a/core/src/xmake/sandbox/interactive.c
+++ b/core/src/xmake/sandbox/interactive.c
@@ -51,6 +51,11 @@
// buffer size for prompt
#define LUA_PROMPT_BUFSIZE 4096
+// for lua5.4
+#ifndef LUA_QL
+# define LUA_QL(x) "'" x "'"
+#endif
+
/* //////////////////////////////////////////////////////////////////////////////////////
* private implementation
*/
@@ -253,7 +258,7 @@ static tb_int_t xm_sandbox_loadline(lua_State* lua, tb_int_t top)
* stack: arg1(sandbox_scope) scriptbuffer(top) -> ...
* after: arg1(sandbox_scope) scriptbuffer scriptfunc(top) -> ...
*/
- status = luaL_loadbuffer(lua, lua_tostring(lua, -1), lua_strlen(lua, -1), "=stdin");
+ status = luaL_loadbuffer(lua, lua_tostring(lua, -1), (size_t)lua_strlen(lua, -1), "=stdin");
// complete?
if (!xm_sandbox_incomplete(lua, status)) break;
@@ -318,8 +323,17 @@ tb_int_t xm_sandbox_interactive(lua_State* lua)
*
* stack: arg1(top) scriptfunc arg1(sandbox_scope) -> ...
*/
+#ifdef USE_LUAJIT
lua_pushvalue(lua, 1);
lua_setfenv(lua, -2);
+#else
+ // stack: arg1(top) scriptfunc $interactive_setfenv scriptfunc arg1(sandbox_scope) -> ...
+ lua_getfield(lua, 1, "$interactive_setfenv");
+ lua_pushvalue(lua, -2);
+ lua_pushvalue(lua, 1);
+ if (lua_pcall(lua, 2, 0, 0) != 0)
+ tb_printl(lua_pushfstring(lua, "error calling " LUA_QL("$interactive_setfenv") " (%s)", lua_tostring(lua, -1)));
+#endif
/* run script
*
diff --git a/core/src/xmake/semver/select.c b/core/src/xmake/semver/select.c
index 221baf46d..e820010b5 100644
--- a/core/src/xmake/semver/select.c
+++ b/core/src/xmake/semver/select.c
@@ -68,7 +68,7 @@ static tb_bool_t xm_semver_select_from_versions_tags1(lua_State* lua, tb_int_t f
lua_pushstring(lua, top.raw);
lua_setfield(lua, -2, "version");
- lua_pushstring(lua, fromidx == 2? "versions" : "tags");
+ lua_pushstring(lua, fromidx == 2? "version" : "tag");
lua_setfield(lua, -2, "source");
// exit the popped semver
@@ -87,12 +87,13 @@ static tb_bool_t xm_semver_select_from_versions_tags2(lua_State* lua, tb_int_t f
lua_gettable(lua, fromidx);
tb_char_t const* source_str = luaL_checkstring(lua, -1);
- if (source_str && tb_strncmp(source_str, version_str, version_len) == 0)
+ tb_size_t source_len = tb_strlen(source_str);
+ if (source_len == version_len && tb_strncmp(source_str, version_str, version_len) == 0)
{
lua_createtable(lua, 0, 2);
- lua_pushstring(lua, source_str);
+ lua_pushlstring(lua, source_str, source_len);
lua_setfield(lua, -2, "version");
- lua_pushstring(lua, fromidx == 2? "versions" : "tags");
+ lua_pushstring(lua, fromidx == 2? "version" : "tag");
lua_setfield(lua, -2, "source");
return tb_true;
}
@@ -109,25 +110,17 @@ static tb_bool_t xm_semver_select_from_branches(lua_State* lua, tb_int_t fromidx
lua_gettable(lua, fromidx);
tb_char_t const* source_str = luaL_checkstring(lua, -1);
- tb_check_continue(source_str);
-
tb_size_t source_len = tb_strlen(source_str);
if (source_len == range_len && tb_memcmp(source_str, range_str, source_len) == 0)
{
lua_createtable(lua, 0, 2);
-
lua_pushlstring(lua, source_str, source_len);
lua_setfield(lua, -2, "version");
-
- lua_pushstring(lua, "branches");
+ lua_pushstring(lua, "branch");
lua_setfield(lua, -2, "source");
-
- // ok
return tb_true;
}
}
-
- // no matches
return tb_false;
}
static tb_bool_t xm_semver_select_latest_from_versions_tags(lua_State* lua, tb_int_t fromidx, semver_t* semver, semvers_t* matches)
@@ -147,8 +140,6 @@ static tb_bool_t xm_semver_select_latest_from_versions_tags(lua_State* lua, tb_i
if (source_str && semver_tryn(semver, source_str, tb_strlen(source_str)) == 0)
semvers_ppush(matches, *semver);
}
-
- // no matches?
tb_check_return_val(matches->length, tb_false);
// sort matches
@@ -162,13 +153,10 @@ static tb_bool_t xm_semver_select_latest_from_versions_tags(lua_State* lua, tb_i
lua_pushstring(lua, top.raw);
lua_setfield(lua, -2, "version");
- lua_pushstring(lua, fromidx == 2? "versions" : "tags");
+ lua_pushstring(lua, fromidx == 2? "version" : "tag");
lua_setfield(lua, -2, "source");
- // exit the popped semver
semver_dtor(&top);
-
- // ok
return tb_true;
}
diff --git a/core/src/xmake/string/endswith.c b/core/src/xmake/string/endswith.c
index df574b657..8f64dbda6 100644
--- a/core/src/xmake/string/endswith.c
+++ b/core/src/xmake/string/endswith.c
@@ -48,7 +48,6 @@ tb_int_t xm_string_endswith(lua_State* lua)
// string:endswith(suffix)?
lua_pushboolean(lua, string_size >= suffix_size && !tb_strcmp(string + string_size - suffix_size, suffix));
-
// ok
return 1;
}
diff --git a/core/src/xmake/tty/prefix.h b/core/src/xmake/tty/prefix.h
new file mode 100644
index 000000000..d1fa5ba07
--- /dev/null
+++ b/core/src/xmake/tty/prefix.h
@@ -0,0 +1,32 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file prefix.h
+ *
+ */
+#ifndef XM_TTY_PREFIX_H
+#define XM_TTY_PREFIX_H
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "../prefix.h"
+
+
+#endif
+
+
diff --git a/core/src/xmake/tty/term_mode.c b/core/src/xmake/tty/term_mode.c
new file mode 100644
index 000000000..975c8fc37
--- /dev/null
+++ b/core/src/xmake/tty/term_mode.c
@@ -0,0 +1,73 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file term_mode.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "term_mode"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+#ifdef TB_CONFIG_OS_WINDOWS
+# include <windows.h>
+#endif
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* local oldmode = tty.term_mode(stdtype)
+ * local oldmode = tty.term_mode(stdtype, newmode)
+ */
+tb_int_t xm_tty_term_mode(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+#ifdef TB_CONFIG_OS_WINDOWS
+
+ // get std type, (stdin: 1, stdout: 2, stderr: 3)
+ tb_int_t stdtype = (tb_int_t)luaL_checkinteger(lua, 1);
+
+ // get and set terminal mode
+ DWORD mode = 0;
+ HANDLE console_handle;
+ switch (stdtype)
+ {
+ case 1: console_handle = GetStdHandle(STD_INPUT_HANDLE); break;
+ case 2: console_handle = GetStdHandle(STD_OUTPUT_HANDLE); break;
+ case 3: console_handle = GetStdHandle(STD_ERROR_HANDLE); break;
+ }
+ GetConsoleMode(console_handle, &mode);
+ if (lua_isnumber(lua, 2))
+ {
+ tb_int_t newmode = (tb_int_t)lua_tointeger(lua, 2);
+ SetConsoleMode(console_handle, (DWORD)newmode);
+ }
+#else
+ tb_int_t mode = 0;
+#endif
+ lua_pushinteger(lua, (tb_int_t)mode);
+ return 1;
+}
diff --git a/core/src/xmake/winos/registry_keys.c b/core/src/xmake/winos/registry_keys.c
index 234cdf035..9c3467210 100644
--- a/core/src/xmake/winos/registry_keys.c
+++ b/core/src/xmake/winos/registry_keys.c
@@ -172,7 +172,7 @@ tb_int_t xm_winos_registry_keys(lua_State* lua)
// get the arguments
tb_char_t const* rootkey = luaL_checkstring(lua, 1);
tb_char_t const* rootdir = luaL_checkstring(lua, 2);
- tb_long_t recursion = lua_tointeger(lua, 3);
+ tb_long_t recursion = (tb_long_t)lua_tointeger(lua, 3);
tb_bool_t is_function = lua_isfunction(lua, 4);
tb_check_return_val(rootkey && rootdir && is_function, 0);
diff --git a/core/src/xmake/winos/short_path.c b/core/src/xmake/winos/short_path.c
new file mode 100644
index 000000000..040b33209
--- /dev/null
+++ b/core/src/xmake/winos/short_path.c
@@ -0,0 +1,79 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file short_path.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "short_path"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* get windows short path from long path
+ *
+ * local short_path, errors = winos.short_path(long_path)
+ */
+tb_int_t xm_winos_short_path(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get the arguments
+ tb_char_t const* long_path = luaL_checkstring(lua, 1);
+ tb_check_return_val(long_path, 0);
+
+ // convert long path to wide characters
+ tb_wchar_t long_path_w[TB_PATH_MAXN];
+ if (tb_atow(long_path_w, long_path, TB_PATH_MAXN) == (tb_size_t)-1)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "invalid long path: %s", long_path);
+ return 2;
+ }
+
+ // get short path
+ tb_wchar_t short_path_w[TB_PATH_MAXN];
+ if (GetShortPathNameW(long_path_w, short_path_w, TB_PATH_MAXN) == 0)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "cannot get short path from: %s", long_path);
+ return 2;
+ }
+
+ // return result
+ tb_char_t* short_path_a = (tb_char_t*)long_path_w;
+ tb_size_t short_path_n = tb_wtoa(short_path_a, short_path_w, TB_PATH_MAXN);
+ if (short_path_n == (tb_size_t)-1)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "invalid short path from %s!", long_path);
+ return 2;
+ }
+ lua_pushlstring(lua, short_path_a, short_path_n);
+ return 1;
+}
diff --git a/core/src/xmake/xmake.config.h.in b/core/src/xmake/xmake.config.h.in
index d4c1f675a..a896b1335 100644
--- a/core/src/xmake/xmake.config.h.in
+++ b/core/src/xmake/xmake.config.h.in
@@ -7,5 +7,7 @@
#define XM_CONFIG_VERSION_MINOR ${VERSION_MINOR}
#define XM_CONFIG_VERSION_ALTER ${VERSION_ALTER}
#define XM_CONFIG_VERSION_BUILD ${VERSION_BUILD}
+#define XM_CONFIG_VERSION_BRANCH "${GIT_BRANCH}"
+#define XM_CONFIG_VERSION_COMMIT "${GIT_COMMIT}"
#endif
diff --git a/core/src/xmake/xmake.lua b/core/src/xmake/xmake.lua
index 7a604301a..0b0693c9b 100644
--- a/core/src/xmake/xmake.lua
+++ b/core/src/xmake/xmake.lua
@@ -7,7 +7,8 @@ target("xmake")
if has_config("curses") or has_config("pdcurses") then
add_deps("lcurses")
end
- add_deps("sv", "luajit", "lua-cjson", "tbox")
+ add_deps("sv", "lua-cjson", "tbox")
+ add_deps(get_config("runtime"))
-- add defines
add_defines("__tb_prefix__=\"xmake\"")
diff --git a/core/xmake.lua b/core/xmake.lua
index e66405e57..552781c76 100644
--- a/core/xmake.lua
+++ b/core/xmake.lua
@@ -2,7 +2,7 @@
set_project("xmake")
-- version
-set_version("2.5.6", {build = "%Y%m%d%H%M"})
+set_version("2.6.2", {build = "%Y%m%d%H%M"})
-- set xmake min version
set_xmakever("2.2.3")
@@ -40,6 +40,14 @@ if is_mode("coverage") then
add_ldflags("-coverage", "-fprofile-arcs", "-ftest-coverage")
end
+-- the runtime option
+option("runtime")
+ set_showmenu(true)
+ set_default("lua")
+ set_description("Use luajit or lua runtime")
+ set_values("luajit", "lua")
+option_end()
+
-- the readline option
option("readline")
set_showmenu(true)
@@ -80,7 +88,7 @@ if is_plat("windows") then
end
-- add projects
-includes("src/lua-cjson", "src/lcurses", "src/sv","src/luajit", "src/tbox", "src/xmake", "src/demo")
+includes("src/lua-cjson", "src/lcurses", "src/sv","src/luajit", "src/lua", "src/tbox", "src/xmake", "src/demo")
if is_plat("windows") then
includes("src/pdcurses")
end
diff --git a/makefile b/makefile
index cc7c61ba1..63d019542 100644
--- a/makefile
+++ b/makefile
@@ -15,6 +15,11 @@ prefix :=$(PREFIX)
endif
endif
+# use luajit or lua backend
+ifeq ($(RUNTIME),)
+RUNTIME :=lua
+endif
+
# the temporary directory
ifeq ($(TMPDIR),)
TMP_DIR :=$(if $(TMP_DIR),$(TMP_DIR),/tmp)
@@ -94,7 +99,7 @@ xrepo_bin_install :=$(destdir)/bin/xrepo
build:
@echo compiling xmake-core ...
@if [ -f core/.config.mak ]; then rm core/.config.mak; fi
- +@$(MAKE) -C core --no-print-directory f DEBUG=$(debug)
+ +@$(MAKE) -C core --no-print-directory f DEBUG=$(debug) RUNTIME=$(RUNTIME)
+@$(MAKE) -C core --no-print-directory c
+@$(MAKE) -C core --no-print-directory
@@ -112,7 +117,8 @@ install:
@if [ ! -d $(destdir)/bin ]; then mkdir -p $(destdir)/bin; fi
@# install the xmake directory
@cp -r xmake/* $(xmake_dir_install)
- @# install the xmake core file
+ @# install the xmake core file, @note we need remove old binary first on mac M1, otherwise it will be killed
+ @if [ -f $(xmake_core_install) ]; then rm $(xmake_core_install); fi
@cp -p $(xmake_core) $(xmake_core_install)
@chmod 755 $(xmake_core_install)
@# install the xrepo bin file
diff --git a/scripts/archlinux/PKGBUILD b/scripts/archlinux/PKGBUILD
index 2d17c0dfe..445e51047 100755
--- a/scripts/archlinux/PKGBUILD
+++ b/scripts/archlinux/PKGBUILD
@@ -2,15 +2,16 @@
# PKGBuild Create By: lumpyzhu <[email protected]>
pkgname=xmake
-pkgver=2.3.2
+pkgver=2.5.9
pkgrel=1
-pkgdesc="A make-like build utility based on Lua"
+pkgdesc="A cross-platform build utility based on Lua"
+depends=('bash')
arch=('i686' 'x86_64')
url="https://github.com/xmake-io/xmake"
license=('Apache')
makedepends=()
-source=("$pkgname.tar.gz::https://github.com/xmake-io/xmake/releases/download/v${pkgver}/xmake-v${pkgver}.tar.gz")
-sha256sums=('b189074320ce1b215f85f8f20142fe173d981eb17c2c157f0fa6756fc00dac4e')
+source=("https://github.com/xmake-io/xmake/releases/download/v${pkgver}/xmake-v${pkgver}.tar.gz")
+sha256sums=('5b50e3f28956cabcaa153624c91781730387ceb7c056f3f9b5306b1c77460d8f')
build() {
cd "$srcdir"
diff --git a/scripts/get.ps1 b/scripts/get.ps1
index 8cb27a888..538220acd 100755
--- a/scripts/get.ps1
+++ b/scripts/get.ps1
@@ -11,6 +11,7 @@ param (
)
& {
+ $LastRelease = "v2.6.2"
$ErrorActionPreference = 'Stop'
function writeErrorTip($msg) {
@@ -30,9 +31,9 @@ param (
}
if ($IsLinux -or $IsMacOS) {
- writeErrorTip 'Install on *nix is not supported, try '
+ writeErrorTip 'Install on *nix is not supported, try '
writeErrorTip '(Use curl) "bash <(curl -fsSL https://raw.githubusercontent.com/xmake-io/xmake/master/scripts/get.sh)"'
- writeErrorTip 'or'
+ writeErrorTip 'or'
writeErrorTip '(Use wget) "bash <(wget https://raw.githubusercontent.com/xmake-io/xmake/master/scripts/get.sh -O -)"'
throw 'Unsupported platform'
}
@@ -90,7 +91,7 @@ param (
$url = if ($v -is [version]) {
"https://github.com/xmake-io/xmake/releases/download/v$v/xmake-v$v.$winarch.exe"
} else {
- "https://ci.appveyor.com/api/projects/waruqi/xmake/artifacts/xmake-installer.exe?branch=$v&pr=false&job=Image%3A+Visual+Studio+2017%3B+Platform%3A+$arch"
+ "https://github.com/xmake-io/xmake/releases/download/$LastRelease/xmake-$v.$winarch.exe"
}
Write-Host "Start downloading $url .."
try {
@@ -145,9 +146,9 @@ param (
writeErrorTip "Please try again as administrator"
return
}
-
+
if ($content) {
- $content = [System.Text.RegularExpressions.Regex]::Replace($content, "\n*(# PowerShell parameter completion shim for xmake)?\s*Register-ArgumentCompleter -Native -CommandName xmake -ScriptBlock\s*{.+?\n}\s*", "`n", [System.Text.RegularExpressions.RegexOptions]::Singleline)
+ $content = [System.Text.RegularExpressions.Regex]::Replace($content, "\n*(# PowerShell parameter completion shim for xmake)?\s*Register-ArgumentCompleter -Native -CommandName xmake -ScriptBlock\s*{.+?\n}\s*", "`n", [System.Text.RegularExpressions.RegexOptions]::Singleline)
}
try {
$appendcontent = (Invoke-Webrequest 'https://xmake.io/assets/scripts/pscompletions.text' -UseBasicParsing).Content
@@ -156,7 +157,7 @@ param (
writeErrorTip 'Check your network or... the news of S3 break'
return
}
- Set-Content $file "$content`n$appendcontent" -NoNewline
+ Set-Content $file "$content`n# >>> xmake >>>`n$appendcontent`n# <<< xmake <<<`n" -NoNewline
. $file
Write-Host "Tab completion installed"
}
diff --git a/scripts/get.sh b/scripts/get.sh
index 8363b4499..ca009407d 100755
--- a/scripts/get.sh
+++ b/scripts/get.sh
@@ -40,7 +40,7 @@ remote_get_content() {
if curl --version >/dev/null 2>&1
then
curl -fSL "$1"
- elif wget --version >/dev/null 2>&1
+ elif wget --version >/dev/null 2>&1 || wget --help >/dev/null 2>&1
then
wget "$1" -O -
fi
@@ -133,32 +133,35 @@ my_exit(){
}
test_tools()
{
- prog='#include <stdio.h>\n#include <readline/readline.h>\nint main(){readline(0);return 0;}'
+ prog='#include <stdio.h>\nint main(){return 0;}'
{
git --version &&
$make --version &&
{
- echo -e "$prog" | cc -xc - -o /dev/null -lreadline ||
- echo -e "$prog" | gcc -xc - -o /dev/null -lreadline ||
- echo -e "$prog" | clang -xc - -o /dev/null -lreadline ||
- echo -e "$prog" | cc -xc - -o /dev/null -I/usr/local/include -L/usr/local/lib -lreadline ||
- echo -e "$prog" | gcc -xc - -o /dev/null -I/usr/local/include -L/usr/local/lib -lreadline ||
- echo -e "$prog" | clang -xc - -o /dev/null -I/usr/local/include -L/usr/local/lib -lreadline
+ echo -e "$prog" | cc -xc - -o /dev/null ||
+ echo -e "$prog" | gcc -xc - -o /dev/null ||
+ echo -e "$prog" | clang -xc - -o /dev/null ||
+ echo -e "$prog" | cc -xc -c - -o /dev/null -I/usr/include -I/usr/local/include ||
+ echo -e "$prog" | gcc -xc -c - -o /dev/null -I/usr/include -I/usr/local/include ||
+ echo -e "$prog" | clang -xc -c - -o /dev/null -I/usr/include -I/usr/local/include
}
} >/dev/null 2>&1
}
install_tools()
{
{ apt --version >/dev/null 2>&1 && $sudoprefix apt install -y git build-essential libreadline-dev ccache; } ||
- { yum --version >/dev/null 2>&1 && $sudoprefix yum install -y git readline-devel ccache && $sudoprefix yum groupinstall -y 'Development Tools'; } ||
+ { yum --version >/dev/null 2>&1 && $sudoprefix yum install -y git readline-devel ccache bzip2 && $sudoprefix yum groupinstall -y 'Development Tools'; } ||
{ zypper --version >/dev/null 2>&1 && $sudoprefix zypper --non-interactive install git readline-devel ccache && $sudoprefix zypper --non-interactive install -t pattern devel_C_C++; } ||
{ pacman -V >/dev/null 2>&1 && $sudoprefix pacman -S --noconfirm --needed git base-devel ccache; } ||
{ emerge -V >/dev/null 2>&1 && $sudoprefix emerge -atv dev-vcs/git ccache; } ||
{ pkg list-installed >/dev/null 2>&1 && $sudoprefix pkg install -y git getconf build-essential readline ccache; } || # termux
{ pkg help >/dev/null 2>&1 && $sudoprefix pkg install -y git readline ccache ncurses; } || # freebsd
- { apk --version >/dev/null 2>&1 && $sudoprefix apk add git gcc g++ make readline-dev ncurses-dev libc-dev linux-headers; }
+ { nix-env --version >/dev/null 2>&1 && nix-env -i git gcc readline ncurses; } || # nixos
+ { apk --version >/dev/null 2>&1 && $sudoprefix apk add git gcc g++ make readline-dev ncurses-dev libc-dev linux-headers; } ||
+ { xbps-install --version >/dev/null 2>&1 && $sudoprefix xbps-install -Sy git base-devel ccache; } #void
+
}
-test_tools || { install_tools && test_tools; } || my_exit "$(echo -e 'Dependencies Installation Fail\nThe getter currently only support these package managers\n\t* apt\n\t* yum\n\t* zypper\n\t* pacman\n\t* portage\nPlease install following dependencies manually:\n\t* git\n\t* build essential like `make`, `gcc`, etc\n\t* libreadline-dev (readline-devel)\n\t* ccache (optional)')" 1
+test_tools || { install_tools && test_tools; } || my_exit "$(echo -e 'Dependencies Installation Fail\nThe getter currently only support these package managers\n\t* apt\n\t* yum\n\t* zypper\n\t* pacman\n\t* portage\n\t* xbps\n Please install following dependencies manually:\n\t* git\n\t* build essential like `make`, `gcc`, etc\n\t* libreadline-dev (readline-devel)\n\t* ccache (optional)')" 1
projectdir=$tmpdir
if [ 'x__local__' = "x$branch" ]; then
if [ -d '.git' ]; then
@@ -222,18 +225,25 @@ else
fi
write_profile()
{
- grep -sq ".xmake/profile" $1 || echo -e "\n[[ -s \"\$HOME/.xmake/profile\" ]] && source \"\$HOME/.xmake/profile\" # load xmake profile" >> $1
+ grep -sq ".xmake/profile" $1 || echo -e "\n# >>> xmake >>>\n[[ -s \"\$HOME/.xmake/profile\" ]] && source \"\$HOME/.xmake/profile\" # load xmake profile\n# <<< xmake <<<" >> $1
}
install_profile()
{
if [ ! -d ~/.xmake ]; then mkdir ~/.xmake; fi
- echo "export PATH=$prefix/bin:\$PATH" > ~/.xmake/profile
+ echo "export XMAKE_ROOTDIR=\"$prefix/bin\"" > ~/.xmake/profile
+ echo 'export PATH="$XMAKE_ROOTDIR:$PATH"' >> ~/.xmake/profile
if [ -f "$projectdir/scripts/register-completions.sh" ]; then
cat "$projectdir/scripts/register-completions.sh" >> ~/.xmake/profile
else
remote_get_content "$gitrepo_raw/scripts/register-completions.sh" >> ~/.xmake/profile
fi
+ if [ -f "$projectdir/scripts/register-virtualenvs.sh" ]; then
+ cat "$projectdir/scripts/register-virtualenvs.sh" >> ~/.xmake/profile
+ else
+ remote_get_content "$gitrepo_raw/scripts/register-virtualenvs.sh" >> ~/.xmake/profile
+ fi
+
if [[ "$SHELL" = */zsh ]]; then
write_profile ~/.zshrc
elif [[ "$SHELL" = */ksh ]]; then
diff --git a/scripts/installer.nsi b/scripts/installer.nsi
index a01b6feea..8ef9e2e6d 100644
--- a/scripts/installer.nsi
+++ b/scripts/installer.nsi
@@ -230,7 +230,12 @@ Section "XMake (required)" InstallExeutable
SetOutPath $InstDir
; Remove previous directories used
- RMDir /r "$InstDir"
+ ; https://github.com/xmake-io/xmake/issues/1888
+ IfFileExists "$InstDir\xmake.exe" file_found file_not_found_or_end
+ file_found:
+ RMDir /r "$InstDir"
+ goto file_not_found_or_end
+ file_not_found_or_end:
; Put file there
File /r /x ".DS_Store" /x "*.swp" "..\xmake\*.*"
@@ -248,7 +253,7 @@ Section "XMake (required)" InstallExeutable
WriteRegStr ${RootKey} ${RegUninstall} "NoAdmin" "$NOADMIN"
; Write the uninstall keys for Windows
- WriteRegStr ${RootKey} ${RegUninstall} "DisplayName" "XMake build utility"
+ WriteRegStr ${RootKey} ${RegUninstall} "DisplayName" "XMake build utility (${ARCH})"
WriteRegStr ${RootKey} ${RegUninstall} "DisplayIcon" '"$InstDir\xmake.exe"'
WriteRegStr ${RootKey} ${RegUninstall} "Comments" "A cross-platform build utility based on Lua"
WriteRegStr ${RootKey} ${RegUninstall} "Publisher" "The TBOOX Open Source Group"
diff --git a/scripts/register-virtualenvs.sh b/scripts/register-virtualenvs.sh
new file mode 100644
index 000000000..6b0c25160
--- /dev/null
+++ b/scripts/register-virtualenvs.sh
@@ -0,0 +1,72 @@
+
+# virtual environments for *nix shell
+
+if test "${XMAKE_ROOTDIR}"; then
+ export XMAKE_EXE=${XMAKE_ROOTDIR}/xmake
+else
+ export XMAKE_EXE=xmake
+fi
+
+function xrepo {
+ if [ $# -ge 2 ] && [ "$1" = "env" ]; then
+ local cmd="${2-x}"
+ case "$cmd" in
+ shell)
+ if test "${XMAKE_PROMPT_BACKUP}"; then
+ PS1="${XMAKE_PROMPT_BACKUP}"
+ source "${XMAKE_ENV_BACKUP}" || return 1
+ unset XMAKE_PROMPT_BACKUP
+ unset XMAKE_ENV_BACKUP
+ fi
+ "$XMAKE_EXE" lua private.xrepo.action.env.info config || return 1
+ local prompt="$("$XMAKE_EXE" lua --quiet private.xrepo.action.env.info prompt)" || return 1
+ if [ -z "${prompt+x}" ]; then
+ return 1
+ fi
+ local activateCommand="$("$XMAKE_EXE" lua private.xrepo.action.env.info script.bash)" || return 1
+ export XMAKE_ENV_BACKUP="$("$XMAKE_EXE" lua private.xrepo.action.env.info envfile)"
+ export XMAKE_PROMPT_BACKUP="${PS1}"
+ "$XMAKE_EXE" lua private.xrepo.action.env.info backup.bash 1>"$XMAKE_ENV_BACKUP"
+ eval "$activateCommand"
+ PS1="${prompt} $PS1"
+ ;;
+ quit)
+ if test "${XMAKE_PROMPT_BACKUP}"; then
+ PS1="${XMAKE_PROMPT_BACKUP}"
+ source "${XMAKE_ENV_BACKUP}" || return 1
+ unset XMAKE_PROMPT_BACKUP
+ unset XMAKE_ENV_BACKUP
+ fi
+ ;;
+ -b|--bind)
+ if [ "$4" = "shell" ]; then
+ local bnd="${3-x}"
+ if test "${XMAKE_PROMPT_BACKUP}"; then
+ PS1="${XMAKE_PROMPT_BACKUP}"
+ source "${XMAKE_ENV_BACKUP}" || return 1
+ unset XMAKE_PROMPT_BACKUP
+ unset XMAKE_ENV_BACKUP
+ fi
+ "$XMAKE_EXE" lua private.xrepo.action.env.info config $bnd || return 1
+ local prompt="$("$XMAKE_EXE" lua --quiet private.xrepo.action.env.info prompt $bnd)" || return 1
+ if [ -z "${prompt+x}" ]; then
+ return 1
+ fi
+ local activateCommand="$("$XMAKE_EXE" lua --quiet private.xrepo.action.env.info script.bash $bnd)" || return 1
+ export XMAKE_ENV_BACKUP="$("$XMAKE_EXE" lua private.xrepo.action.env.info envfile $bnd)"
+ export XMAKE_PROMPT_BACKUP="${PS1}"
+ "$XMAKE_EXE" lua --quiet private.xrepo.action.env.info backup.bash $bnd 1>"$XMAKE_ENV_BACKUP"
+ eval "$activateCommand"
+ PS1="${prompt} $PS1"
+ else
+ "$XMAKE_EXE" lua private.xrepo "$@"
+ fi
+ ;;
+ *)
+ "$XMAKE_EXE" lua private.xrepo "$@"
+ ;;
+ esac
+ else
+ "$XMAKE_EXE" lua private.xrepo "$@"
+ fi
+}
diff --git a/scripts/rpmbuild/SPECS/xmake.spec b/scripts/rpmbuild/SPECS/xmake.spec
index 7c7d5ed38..3485dc68a 100644
--- a/scripts/rpmbuild/SPECS/xmake.spec
+++ b/scripts/rpmbuild/SPECS/xmake.spec
@@ -1,13 +1,14 @@
-%define xmake_revision fd248b8b97f62762ce6ea6e0008b4367bef29d4d
-%define tbox_revision 5ef932750ede0b90867fd4afdcf1deed2464c82b
-%define sv_revision 9a3cf7c8e589de4f70378824329882c4a047fffc
+%define xmake_revision 022ca13475739cee7e10bd0a3256ecd704fb2e6d
+%define tbox_revision 122a479e626ee3fdd7d6c1117ec7c19212a1e087
+%define sv_revision 035262773da0500367cb88e6f30197908159a348
%define lua_cjson_revision 515bab6d6d80b164b94db73af69609ea02f3a798
%define luajit_revision e9af1abec542e6f9851ff2368e7f196b6382a44c
+%define lua_revision eadd8c7178c79c814ecca9652973a9b9dd4cc71b
%define _binaries_in_noarch_packages_terminate_build 0
%undefine _disable_source_fetch
Name: xmake
-Version: 2.5.6
+Version: 2.6.2
Release: 1%{?dist}
Summary: A cross-platform build utility based on Lua
BuildArch: noarch
@@ -15,9 +16,10 @@ License: ASL 2.0
URL: https://xmake.io
Source0: https://github.com/xmake-io/xmake/archive/%{xmake_revision}.tar.gz#/xmake-%{xmake_revision}.tar.gz
Source1: https://github.com/tboox/tbox/archive/%{tbox_revision}.tar.gz#/tbox-%{tbox_revision}.tar.gz
-Source2: https://github.com/xmake-io/xmake-core-luajit/archive/%{luajit_revision}.tar.gz#/xmake-core-luajit-%{luajit_revision}.tar.gz
-Source3: https://github.com/xmake-io/xmake-core-sv/archive/%{sv_revision}.tar.gz#/xmake-core-sv-%{sv_revision}.tar.gz
-Source4: https://github.com/xmake-io/xmake-core-lua-cjson/archive/%{lua_cjson_revision}.tar.gz#/xmake-core-lua-cjson-%{lua_cjson_revision}.tar.gz
+Source2: https://github.com/xmake-io/xmake-core-lua/archive/%{lua_revision}.tar.gz#/xmake-core-lua-%{lua_revision}.tar.gz
+Source3: https://github.com/xmake-io/xmake-core-luajit/archive/%{luajit_revision}.tar.gz#/xmake-core-luajit-%{luajit_revision}.tar.gz
+Source4: https://github.com/xmake-io/xmake-core-sv/archive/%{sv_revision}.tar.gz#/xmake-core-sv-%{sv_revision}.tar.gz
+Source5: https://github.com/xmake-io/xmake-core-lua-cjson/archive/%{lua_cjson_revision}.tar.gz#/xmake-core-lua-cjson-%{lua_cjson_revision}.tar.gz
BuildRequires: gcc-c++
BuildRequires: ncurses-devel
@@ -38,19 +40,23 @@ system to help users solve the integrated use of C/C++ dependent libraries.
%prep
%setup -q -T -b 1 -n tbox-%{tbox_revision}
cd ..
-%setup -q -T -b 2 -n xmake-core-luajit-%{luajit_revision}
+%setup -q -T -b 2 -n xmake-core-lua-%{lua_revision}
cd ..
-%setup -q -T -b 3 -n xmake-core-sv-%{sv_revision}
+%setup -q -T -b 3 -n xmake-core-luajit-%{luajit_revision}
cd ..
-%setup -q -T -b 4 -n xmake-core-lua-cjson-%{lua_cjson_revision}
+%setup -q -T -b 4 -n xmake-core-sv-%{sv_revision}
+cd ..
+%setup -q -T -b 5 -n xmake-core-lua-cjson-%{lua_cjson_revision}
cd ..
%setup -q -T -b 0 -n xmake-%{xmake_revision}
rm -rf core/src/sv/sv
rm -rf core/src/tbox/tbox
+rm -rf core/src/lua/lua
rm -rf core/src/luajit/luajit
rm -rf core/src/lua-cjson/lua-cjson
ln -s `pwd`/../tbox-%{tbox_revision} core/src/tbox/tbox
ln -s `pwd`/../xmake-core-sv-%{sv_revision} core/src/sv/sv
+ln -s `pwd`/../xmake-core-lua-%{lua_revision} core/src/lua/lua
ln -s `pwd`/../xmake-core-luajit-%{luajit_revision} core/src/luajit/luajit
ln -s `pwd`/../xmake-core-lua-cjson-%{lua_cjson_revision} core/src/lua-cjson/lua-cjson
diff --git a/scripts/xrepo.bat b/scripts/xrepo.bat
index c8714a11c..0416d4a10 100755
--- a/scripts/xrepo.bat
+++ b/scripts/xrepo.bat
@@ -22,7 +22,7 @@
if !errorlevel! neq 0 (
exit /B !errorlevel!
)
- @%XMAKE_EXE% lua private.xrepo.action.env.info prompt 1>nul
+ @%XMAKE_EXE% lua --quiet private.xrepo.action.env.info prompt 1>nul
if !errorlevel! neq 0 (
echo error: xmake.lua not found^^!
exit /B !errorlevel!
@@ -39,13 +39,13 @@
if !errorlevel! neq 0 (
exit /B !errorlevel!
)
- @%XMAKE_EXE% lua private.xrepo.action.env.info prompt 1>nul
+ @%XMAKE_EXE% lua --quiet private.xrepo.action.env.info prompt 1>nul
if !errorlevel! neq 0 (
echo error: xmake.lua not found^^!
exit /B !errorlevel!
)
endlocal
- for /f %%i in ('@%XMAKE_EXE% lua private.xrepo.action.env.info prompt') do @(
+ for /f %%i in ('@%XMAKE_EXE% lua --quiet private.xrepo.action.env.info prompt') do @(
@set "PROMPT=%%i %PROMPT%"
)
@set XMAKE_PROMPT_BACKUP=%PROMPT%
@@ -60,6 +60,52 @@
)
goto :ENDXREPO
)
+ set XREPO_BIND_FLAG=
+ if [%2]==[-b] if [%4]==[shell] (
+ set XREPO_BIND_FLAG=1
+ )
+ if [%2]==[--bind] if [%4]==[shell] (
+ set XREPO_BIND_FLAG=1
+ )
+ if defined XREPO_BIND_FLAG (
+ set XREPO_BIND_FLAG=
+ if defined XMAKE_PROMPT_BACKUP (
+ call %XMAKE_ENV_BACKUP%
+ setlocal EnableDelayedExpansion
+ if !errorlevel! neq 0 exit /B !errorlevel!
+ endlocal
+ set PROMPT=%XMAKE_PROMPT_BACKUP%
+ set XMAKE_ENV_BACKUP=
+ set XMAKE_PROMPT_BACKUP=
+ echo Please rerun `xrepo env shell` to enter the environment.
+ exit /B 1
+ ) else (
+ setlocal EnableDelayedExpansion
+ %XMAKE_EXE% lua private.xrepo.action.env.info config %3
+ if !errorlevel! neq 0 (
+ exit /B !errorlevel!
+ )
+ @%XMAKE_EXE% lua --quiet private.xrepo.action.env.info prompt %3 1>nul
+ if !errorlevel! neq 0 (
+ echo error: environment not found^^!
+ exit /B !errorlevel!
+ )
+ endlocal
+ for /f %%i in ('@%XMAKE_EXE% lua --quiet private.xrepo.action.env.info prompt %3') do @(
+ @set "PROMPT=%%i %PROMPT%"
+ )
+ @set XMAKE_PROMPT_BACKUP=%PROMPT%
+ )
+ for /f %%i in ('@%XMAKE_EXE% lua private.xrepo.action.env.info envfile %3') do @(
+ @set "XMAKE_ENV_BACKUP=%%i.bat"
+ @"%XMAKE_EXE%" lua --quiet private.xrepo.action.env.info backup.cmd %3 1>"%%i.bat"
+ )
+ for /f %%i in ('@%XMAKE_EXE% lua private.xrepo.action.env.info envfile %3') do @(
+ @"%XMAKE_EXE%" lua --quiet private.xrepo.action.env.info script.cmd %3 1>"%%i.bat"
+ call "%%i.bat"
+ )
+ goto :ENDXREPO
+ )
)
@call %XMAKE_EXE% lua private.xrepo %*
diff --git a/scripts/xrepo.ps1 b/scripts/xrepo.ps1
index a821d8057..74e5e4682 100644
--- a/scripts/xrepo.ps1
+++ b/scripts/xrepo.ps1
@@ -19,13 +19,27 @@ if ($Args.Count -eq 0) {
if ((Test-Path 'Env:XMAKE_PROMPT_MODIFIER') -and ($Env:XMAKE_PROMPT_MODIFIER -ne "")) {
Exit-XrepoEnvironment;
}
- Enter-XrepoEnvironment;
+ Enter-XrepoEnvironment $Null;
return;
}
"quit" {
Exit-XrepoEnvironment;
return;
}
+ {$_ -in "-b", "--bind"} {
+ if (($Args.Count -ge 4) -and ($Args[3] -eq "shell")) {
+ if (-not (Test-Path 'Env:XMAKE_ROOTDIR')) {
+ $Env:XMAKE_ROOTDIR = $BASE_DIR;
+ Import-Module "$Env:XMAKE_ROOTDIR\scripts\xrepo-hook.psm1";
+ Add-XrepoEnvironmentToPrompt;
+ }
+ if ((Test-Path 'Env:XMAKE_PROMPT_MODIFIER') -and ($Env:XMAKE_PROMPT_MODIFIER -ne "")) {
+ Exit-XrepoEnvironment;
+ }
+ Enter-XrepoEnvironment $Args[2];
+ return;
+ }
+ }
}
}
diff --git a/tests/apis/add_configfiles/config.h.in b/tests/apis/add_configfiles/config.h.in
index 3cbeb4135..c1ea00299 100644
--- a/tests/apis/add_configfiles/config.h.in
+++ b/tests/apis/add_configfiles/config.h.in
@@ -4,7 +4,10 @@
${define FOO_ENABLE}
${define FOO_ENABLE2}
${define FOO_STRING}
+${define FOO_DEFINE}
${define FOO2_ENABLE}
${define FOO2_ENABLE2}
${define FOO2_STRING}
+
+#define HAVE_SSE2 ${default HAVE_SSE2 0}
diff --git a/tests/apis/add_configfiles/xmake.lua b/tests/apis/add_configfiles/xmake.lua
index 0dcf1eceb..a6849d586 100644
--- a/tests/apis/add_configfiles/xmake.lua
+++ b/tests/apis/add_configfiles/xmake.lua
@@ -8,6 +8,7 @@ if has_config("foo") then
set_configvar("FOO_ENABLE", 1)
set_configvar("FOO_ENABLE2", false)
set_configvar("FOO_STRING", get_config("foo"))
+ set_configvar("FOO_DEFINE", get_config("foo"), {quote = false})
end
option("foo2")
diff --git a/tests/apis/check_xxx/config.h.in b/tests/apis/check_xxx/config.h.in
index c5e178b44..9dedbaf96 100644
--- a/tests/apis/check_xxx/config.h.in
+++ b/tests/apis/check_xxx/config.h.in
@@ -1,6 +1,5 @@
${define HAS_STRING_H}
${define HAS_STRING_AND_STDIO_H}
-${define HAS_WCHAR}
${define HAS_WCHAR_AND_FLOAT}
${define HAS_PTHREAD}
${define HAS_STATIC_ASSERT}
@@ -8,3 +7,20 @@ ${define HAS_SETJMP}
${define HAS_CONSTEXPR}
${define HAS_CONSEXPR_AND_STATIC_ASSERT}
${define HAS_SSE2}
+${define HAS_LONG_8}
+${define HAS_CXX_STD_98}
+${define HAS_CXX_STD_11}
+${define HAS_CXX_STD_14}
+${define HAS_CXX_STD_17}
+${define HAS_CXX_STD_20}
+${define HAS_C_STD_89}
+${define HAS_C_STD_99}
+${define HAS_C_STD_11}
+${define HAS_C_STD_17}
+${define HAS_GCC}
+${define HAS_CXX20}
+${define NO_GCC}
+${define PTR_SIZE}
+${define HAVE_VISIBILITY}
+${define CUSTOM_ASSERT}
+#define HAS_WCHAR ${default HAS_WCHAR 0}
diff --git a/tests/apis/check_xxx/foo.c b/tests/apis/check_xxx/foo.c
new file mode 100644
index 000000000..c055f5886
--- /dev/null
+++ b/tests/apis/check_xxx/foo.c
@@ -0,0 +1,6 @@
+#include "config.h"
+
+int foo()
+{
+ return 0;
+}
diff --git a/tests/apis/check_xxx/main.c b/tests/apis/check_xxx/main.c
index 5549c309f..e5a9ccbdf 100644
--- a/tests/apis/check_xxx/main.c
+++ b/tests/apis/check_xxx/main.c
@@ -1,4 +1,3 @@
-
int main(int argc, char** argv)
{
return 0;
diff --git a/tests/apis/check_xxx/xmake.lua b/tests/apis/check_xxx/xmake.lua
index a2a5fa0b1..d5ed6e2fb 100644
--- a/tests/apis/check_xxx/xmake.lua
+++ b/tests/apis/check_xxx/xmake.lua
@@ -2,17 +2,21 @@ includes("check_links.lua")
includes("check_ctypes.lua")
includes("check_cflags.lua")
includes("check_cfuncs.lua")
+includes("check_macros.lua")
includes("check_features.lua")
includes("check_csnippets.lua")
includes("check_cincludes.lua")
-target("test")
- set_kind("binary")
- add_files("*.c")
+target("foo")
+ set_kind("static")
+ add_files("foo.c")
+ add_includedirs("$(buildir)")
add_configfiles("config.h.in")
check_ctypes("HAS_WCHAR", "wchar_t")
check_cincludes("HAS_STRING_H", "string.h")
+ check_csnippets("HAS_INT_4", "return (sizeof(int) == 4)? 0 : -1;", {tryrun = true})
+ check_csnippets("INT_SIZE", 'printf("%d", sizeof(int)); return 0;', {output = true, number = true})
configvar_check_cincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"})
configvar_check_ctypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"})
configvar_check_links("HAS_PTHREAD", {"pthread", "m", "dl"})
@@ -20,4 +24,75 @@ target("test")
configvar_check_cfuncs("HAS_SETJMP", "setjmp", {includes = {"signal.h", "setjmp.h"}})
configvar_check_features("HAS_CONSTEXPR", "cxx_constexpr", {languages = "c++11"})
configvar_check_features("HAS_CONSEXPR_AND_STATIC_ASSERT", {"cxx_constexpr", "c_static_assert"}, {languages = "c++11"})
+ configvar_check_features("HAS_CXX_STD_98", "cxx_std_98")
+ configvar_check_features("HAS_CXX_STD_11", "cxx_std_11", {languages = "c++11"})
+ configvar_check_features("HAS_CXX_STD_14", "cxx_std_14", {languages = "c++14"})
+ configvar_check_features("HAS_CXX_STD_17", "cxx_std_17", {languages = "c++17"})
+ configvar_check_features("HAS_CXX_STD_20", "cxx_std_20", {languages = "c++20"})
+ configvar_check_features("HAS_C_STD_89", "c_std_89")
+ configvar_check_features("HAS_C_STD_99", "c_std_99")
+ configvar_check_features("HAS_C_STD_11", "c_std_11", {languages = "c11"})
+ configvar_check_features("HAS_C_STD_17", "c_std_17", {languages = "c17"})
configvar_check_cflags("HAS_SSE2", "-msse2")
+ configvar_check_csnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true})
+ configvar_check_csnippets("PTR_SIZE", 'printf("%d", sizeof(void*)); return 0;', {output = true, number = true})
+ configvar_check_csnippets("HAVE_VISIBILITY", 'extern __attribute__((__visibility__("hidden"))) int hiddenvar;', {default = 0})
+ configvar_check_csnippets("CUSTOM_ASSERT=assert", 'assert(1);', {default = "", quote = false})
+ configvar_check_macros("HAS_GCC", "__GNUC__")
+ configvar_check_macros("NO_GCC", "__GNUC__", {defined = false})
+ configvar_check_macros("HAS_CXX20", "__cplusplus >= 202002L", {languages = "c++20"})
+
+ local features_cxx17 = {
+ "cxx_aggregate_bases",
+ "cxx_aligned_new",
+ "cxx_capture_star_this",
+ "cxx_constexpr",
+ "cxx_deduction_guides",
+ "cxx_enumerator_attributes",
+ "cxx_fold_expressions",
+ "cxx_guaranteed_copy_elision",
+ "cxx_hex_float",
+ "cxx_if_constexpr",
+ "cxx_inheriting_constructors",
+ "cxx_inline_variables",
+ "cxx_namespace_attributes",
+ "cxx_noexcept_function_type",
+ "cxx_nontype_template_args",
+ "cxx_nontype_template_parameter_auto",
+ "cxx_range_based_for",
+ "cxx_static_assert",
+ "cxx_structured_bindings",
+ "cxx_template_template_args",
+ "cxx_variadic_using"}
+ for _, feature in ipairs(features_cxx17) do
+ check_features("HAS_17_" .. feature:upper(), feature, {languages = "c++17"})
+ end
+
+ local features_cxx20 = {
+ "cxx_aggregate_paren_init",
+ "cxx_char8_t",
+ "cxx_concepts",
+ "cxx_conditional_explicit",
+ "cxx_consteval",
+ "cxx_constexpr",
+ "cxx_constexpr_dynamic_alloc",
+ "cxx_constexpr_in_decltype",
+ "cxx_constinit",
+ "cxx_deduction_guides",
+ "cxx_designated_initializers",
+ "cxx_generic_lambdas",
+ "cxx_impl_coroutine",
+ "cxx_impl_destroying_delete",
+ "cxx_impl_three_way_comparison",
+ "cxx_init_captures",
+ "cxx_modules",
+ "cxx_nontype_template_args",
+ "cxx_using_enum"}
+ for _, feature in ipairs(features_cxx20) do
+ check_features("HAS_20_" .. feature:upper(), feature, {languages = "c++20"})
+ end
+
+target("test")
+ add_deps("foo")
+ set_kind("binary")
+ add_files("main.c")
diff --git a/tests/apis/rules/xmake.lua b/tests/apis/rules/xmake.lua
index 276b4c074..5a6e5d546 100644
--- a/tests/apis/rules/xmake.lua
+++ b/tests/apis/rules/xmake.lua
@@ -27,7 +27,7 @@ rule("c code")
end)
on_build_file(function (target, sourcefile, opt)
import("core.theme.theme")
- import("private.utils.progress")
+ import("utils.progress")
progress.show(opt.progress, "compiling.$(mode) %s", sourcefile)
local objectfile_o = os.tmpfile() .. ".o"
local sourcefile_c = os.tmpfile() .. ".c"
diff --git a/tests/apis/set_toolchains/xmake.lua b/tests/apis/set_toolchains/xmake.lua
index 83bdb4a5e..9db80f107 100644
--- a/tests/apis/set_toolchains/xmake.lua
+++ b/tests/apis/set_toolchains/xmake.lua
@@ -10,7 +10,6 @@ toolchain("myclang")
set_toolset("ld", "clang++", "clang")
set_toolset("sh", "clang++", "clang")
set_toolset("ar", "ar")
- set_toolset("ex", "ar")
set_toolset("strip", "strip")
set_toolset("mm", "clang")
set_toolset("mxx", "clang", "clang++")
diff --git a/tests/modules/heap/test.lua b/tests/modules/heap/test.lua
index 098116f28..fc11a49d2 100644
--- a/tests/modules/heap/test.lua
+++ b/tests/modules/heap/test.lua
@@ -1,6 +1,9 @@
import("core.base.heap")
function test_cdataheap(t)
+ if not xmake.luajit() then
+ return
+ end
local h = heap.cdataheap{
size = 100,
ctype = [[
diff --git a/tests/modules/semver/test.lua b/tests/modules/semver/test.lua
index f39f3acde..5141f099c 100755
--- a/tests/modules/semver/test.lua
+++ b/tests/modules/semver/test.lua
@@ -10,21 +10,21 @@ end
-- test select version
function test_semver_select(t)
- _check_semver_select(t, {"1.5.1", "versions"}
+ _check_semver_select(t, {"1.5.1", "version"}
, ">=1.5.0 <1.6.0"
, {"1.4.0", "1.5.0", "1.5.1"})
- _check_semver_select(t, {"1.5.1", "versions"}
+ _check_semver_select(t, {"1.5.1", "version"}
, "^1.5.0"
,{"1.4.0", "1.5.0", "1.5.1"})
- _check_semver_select(t, {"master", "branches"}
+ _check_semver_select(t, {"master", "branch"}
, "master"
, {"1.4.0", "1.5.0", "1.5.1"}
, {"v1.2.0", "v1.6.0"}
, {"master", "dev"})
- _check_semver_select(t, {"1.5.1", "versions"}
+ _check_semver_select(t, {"1.5.1", "version"}
, "latest"
, {"1.4.0", "1.5.0", "1.5.1"})
end
diff --git a/tests/modules/string/serialize/test.lua b/tests/modules/string/serialize/test.lua
index 3c21d4410..dfbd01c09 100644
--- a/tests/modules/string/serialize/test.lua
+++ b/tests/modules/string/serialize/test.lua
@@ -62,7 +62,10 @@ function test_function(t)
-- return x in fenv
function f() return x end
-- fenv will restore
- t:are_same(roundtrip(f)(), x)
+ if xmake.luajit() then
+ -- TODO we need fix it for lua backend
+ t:are_same(roundtrip(f)(), x)
+ end
y = {}
-- y in fenv
diff --git a/tests/modules/table/test.lua b/tests/modules/table/test.lua
new file mode 100644
index 000000000..5ed17620c
--- /dev/null
+++ b/tests/modules/table/test.lua
@@ -0,0 +1,11 @@
+function test_remove_if(t)
+ t:are_equal(table.remove_if({1, 2, 3, 4, 5, 6}, function (i, v) return (v % 2) == 0 end), {1, 3, 5})
+ t:are_equal(table.remove_if({a = 1, b = 2, c = 3}, function (i, v) return (v % 2) == 0 end), {a = 1, c = 3})
+end
+
+function test_find_if(t)
+ t:are_equal(table.find_if({1, 2, 3, 4, 5, 6}, function (i, v) return (v % 2) == 0 end), {2, 4, 6})
+ t:are_equal(table.find_first_if({1, 2, 3, 4, 5, 6}, function (i, v) return (v % 2) == 0 end), 2)
+ t:are_equal(table.find({1, 2, 4, 4, 5, 6}, 4), {3, 4})
+ t:are_equal(table.find_first({1, 2, 3, 4, 5, 6}, 4), 4)
+end
diff --git a/tests/projects/c++/modules/class/src/hello.mpp b/tests/projects/c++/modules/class/src/hello.mpp
index 9e4ecd960..268964aa3 100644
--- a/tests/projects/c++/modules/class/src/hello.mpp
+++ b/tests/projects/c++/modules/class/src/hello.mpp
@@ -5,8 +5,7 @@ export namespace hello {
public:
say(int data);
void hello();
-
private:
int data_;
};
-} \ No newline at end of file
+}
diff --git a/tests/projects/c++/modules/class/src/hello_impl.cpp b/tests/projects/c++/modules/class/src/hello_impl.cpp
index 6d0008fbb..5dd555a7a 100644
--- a/tests/projects/c++/modules/class/src/hello_impl.cpp
+++ b/tests/projects/c++/modules/class/src/hello_impl.cpp
@@ -1,14 +1,13 @@
-module hello;
-
+module;
#include <iostream>
-using namespace std;
+module hello;
+using namespace std;
namespace hello {
say::say(int data) : data_(data) {
}
-
void say::hello() {
cout << "hello, say class: " << data_ << endl;
}
diff --git a/tests/projects/c++/modules/dependence/src/hello.mpp b/tests/projects/c++/modules/dependence/src/hello.mpp
index 3f803afaf..abac9fcb0 100644
--- a/tests/projects/c++/modules/dependence/src/hello.mpp
+++ b/tests/projects/c++/modules/dependence/src/hello.mpp
@@ -1,27 +1,14 @@
export module hello;
export namespace hello {
-#ifdef _MSC_VER
- int data__;
-#else
extern int data__;
-#endif
void say_hello();
class say {
public:
say(int data);
void hello();
-
private:
int data_;
};
}
-/*
-#ifndef _MSC_VER
-export namespace {
- void anonymous() {
- }
-}
-#endif
-*/ \ No newline at end of file
diff --git a/tests/projects/c++/modules/dependence/src/hello_impl.cpp b/tests/projects/c++/modules/dependence/src/hello_impl.cpp
index 5dbc009f4..064afebad 100644
--- a/tests/projects/c++/modules/dependence/src/hello_impl.cpp
+++ b/tests/projects/c++/modules/dependence/src/hello_impl.cpp
@@ -1,6 +1,7 @@
-module hello;
-
+module;
#include <iostream>
+
+module hello;
import mod;
void inner() {
@@ -13,7 +14,6 @@ namespace hello {
void say_hello() { ::inner(); }
say::say(int data) : data_{data} {
-
}
void say::hello() {
diff --git a/tests/projects/c++/modules/dependence2/src/bar.mpp b/tests/projects/c++/modules/dependence2/src/bar.mpp
new file mode 100644
index 000000000..140924a85
--- /dev/null
+++ b/tests/projects/c++/modules/dependence2/src/bar.mpp
@@ -0,0 +1,8 @@
+export module bar;
+import zoo;
+
+export namespace bar {
+ int add(int a, int b) {
+ return zoo::add(a, b);
+ }
+}
diff --git a/tests/projects/c++/modules/dependence2/src/cat.mpp b/tests/projects/c++/modules/dependence2/src/cat.mpp
new file mode 100644
index 000000000..652940c08
--- /dev/null
+++ b/tests/projects/c++/modules/dependence2/src/cat.mpp
@@ -0,0 +1,8 @@
+export module cat;
+
+export namespace cat {
+ int sub(int a, int b) {
+ return a - b;
+ }
+}
+
diff --git a/tests/projects/c++/modules/dependence2/src/foo.mpp b/tests/projects/c++/modules/dependence2/src/foo.mpp
new file mode 100644
index 000000000..5aac74086
--- /dev/null
+++ b/tests/projects/c++/modules/dependence2/src/foo.mpp
@@ -0,0 +1,13 @@
+export module foo;
+import bar;
+import cat;
+
+export namespace foo {
+ int add(int a, int b) {
+ return bar::add(a, b);
+ }
+ int sub(int a, int b) {
+ return cat::sub(a, b);
+ }
+}
+
diff --git a/tests/projects/c++/modules/dependence2/src/main.cpp b/tests/projects/c++/modules/dependence2/src/main.cpp
new file mode 100644
index 000000000..b5c04f1b2
--- /dev/null
+++ b/tests/projects/c++/modules/dependence2/src/main.cpp
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+import foo;
+
+int main() {
+ printf("add(1, 2): %d\n", foo::add(1, 2));
+ printf("sub(1, 2): %d\n", foo::sub(1, 2));
+ return 0;
+}
+
diff --git a/tests/projects/c++/modules/dependence2/src/zoo.mpp b/tests/projects/c++/modules/dependence2/src/zoo.mpp
new file mode 100644
index 000000000..60c86ddf6
--- /dev/null
+++ b/tests/projects/c++/modules/dependence2/src/zoo.mpp
@@ -0,0 +1,8 @@
+export module zoo;
+
+export namespace zoo {
+ int add(int a, int b) {
+ return a + b;
+ }
+}
+
diff --git a/tests/projects/c++/modules/dependence2/xmake.lua b/tests/projects/c++/modules/dependence2/xmake.lua
new file mode 100644
index 000000000..6d64b49b1
--- /dev/null
+++ b/tests/projects/c++/modules/dependence2/xmake.lua
@@ -0,0 +1,4 @@
+set_languages("c++20")
+target("dependence")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
diff --git a/tests/projects/c++/modules/hello/src/hello.mpp b/tests/projects/c++/modules/hello/src/hello.mpp
index 9bbd036f0..124bd72bc 100644
--- a/tests/projects/c++/modules/hello/src/hello.mpp
+++ b/tests/projects/c++/modules/hello/src/hello.mpp
@@ -1,11 +1,10 @@
-export module hello;
-
+module;
#include <cstdio>
-using namespace std;
+export module hello;
export namespace hello {
void say(const char* str) {
printf("%s\n", str);
}
-} \ No newline at end of file
+}
diff --git a/tests/projects/c++/modules/hello/src/main.cpp b/tests/projects/c++/modules/hello/src/main.cpp
index 175b4d348..1e5cc698f 100644
--- a/tests/projects/c++/modules/hello/src/main.cpp
+++ b/tests/projects/c++/modules/hello/src/main.cpp
@@ -3,4 +3,4 @@ import hello;
int main() {
hello::say("hello module!");
return 0;
-} \ No newline at end of file
+}
diff --git a/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp b/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
index 9cee17cfd..eccfed5d3 100644
--- a/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
+++ b/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
@@ -1,7 +1,7 @@
-module hello;
-
+module;
#include <iostream>
+module hello;
using namespace std;
namespace hello {
diff --git a/tests/projects/c++/modules/inline_and_template/src/hello.mpp b/tests/projects/c++/modules/inline_and_template/src/hello.mpp
index c36d54783..94d40ddaa 100644
--- a/tests/projects/c++/modules/inline_and_template/src/hello.mpp
+++ b/tests/projects/c++/modules/inline_and_template/src/hello.mpp
@@ -1,9 +1,9 @@
-export module hello;
-
+module;
#include <cstdio>
+export module hello;
export namespace hello {
inline void say_hello() {
std::printf("hello world!\n");
}
-} \ No newline at end of file
+}
diff --git a/tests/projects/c++/modules/inline_and_template/src/say.mpp b/tests/projects/c++/modules/inline_and_template/src/say.mpp
index b4d05a5f4..ab3290cf9 100644
--- a/tests/projects/c++/modules/inline_and_template/src/say.mpp
+++ b/tests/projects/c++/modules/inline_and_template/src/say.mpp
@@ -1,11 +1,11 @@
-export module say;
-
+module;
#include <cstdio>
+export module say;
export class say {
public:
template <int N>
void hello() {
std::printf("hello, say class: %d\n", N);
}
-}; \ No newline at end of file
+};
diff --git a/tests/projects/c++/modules/partitions/src/main.cpp b/tests/projects/c++/modules/partitions/src/main.cpp
new file mode 100644
index 000000000..058dfd522
--- /dev/null
+++ b/tests/projects/c++/modules/partitions/src/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+
+import math;
+
+int main() {
+
+ std::cout << std::endl;
+
+ std::cout << "add(3, 4): " << add(3, 4) << std::endl;
+ std::cout << "mul(3, 4): " << mul(3, 4) << std::endl;
+}
diff --git a/tests/projects/c++/modules/partitions/src/math.math1.mpp b/tests/projects/c++/modules/partitions/src/math.math1.mpp
new file mode 100644
index 000000000..8537d161a
--- /dev/null
+++ b/tests/projects/c++/modules/partitions/src/math.math1.mpp
@@ -0,0 +1,5 @@
+export module math:math1;
+
+export int add(int fir, int sec) {
+ return fir + sec;
+}
diff --git a/tests/projects/c++/modules/partitions/src/math.math2.mpp b/tests/projects/c++/modules/partitions/src/math.math2.mpp
new file mode 100644
index 000000000..78e14ed6f
--- /dev/null
+++ b/tests/projects/c++/modules/partitions/src/math.math2.mpp
@@ -0,0 +1,7 @@
+export module math:math2;
+
+export {
+ int mul(int fir, int sec) {
+ return fir * sec;
+ }
+}
diff --git a/tests/projects/c++/modules/partitions/src/math.mpp b/tests/projects/c++/modules/partitions/src/math.mpp
new file mode 100644
index 000000000..11402ade6
--- /dev/null
+++ b/tests/projects/c++/modules/partitions/src/math.mpp
@@ -0,0 +1,4 @@
+export module math;
+
+export import :math1;
+export import :math2;
diff --git a/tests/projects/c++/modules/partitions/xmake.lua b/tests/projects/c++/modules/partitions/xmake.lua
new file mode 100644
index 000000000..672034947
--- /dev/null
+++ b/tests/projects/c++/modules/partitions/xmake.lua
@@ -0,0 +1,4 @@
+set_languages("c++20")
+target("math")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
diff --git a/tests/projects/c++/modules/staticlib/src/main.cpp b/tests/projects/c++/modules/staticlib/src/main.cpp
new file mode 100644
index 000000000..af2c328eb
--- /dev/null
+++ b/tests/projects/c++/modules/staticlib/src/main.cpp
@@ -0,0 +1,8 @@
+#include <stdio.h>
+import mod;
+
+int main() {
+ printf("%d\n", mod::foo());
+ return 0;
+}
+
diff --git a/tests/projects/c++/modules/staticlib/src/mod.cpp b/tests/projects/c++/modules/staticlib/src/mod.cpp
new file mode 100644
index 000000000..9c7cf5290
--- /dev/null
+++ b/tests/projects/c++/modules/staticlib/src/mod.cpp
@@ -0,0 +1,7 @@
+module mod;
+
+namespace mod {
+ int foo() {
+ return 2;
+ }
+}
diff --git a/tests/projects/c++/modules/staticlib/src/mod.mpp b/tests/projects/c++/modules/staticlib/src/mod.mpp
new file mode 100644
index 000000000..ac30a31c8
--- /dev/null
+++ b/tests/projects/c++/modules/staticlib/src/mod.mpp
@@ -0,0 +1,5 @@
+export module mod;
+
+export namespace mod {
+ int foo();
+}
diff --git a/tests/projects/c++/modules/staticlib/xmake.lua b/tests/projects/c++/modules/staticlib/xmake.lua
new file mode 100644
index 000000000..93045c18f
--- /dev/null
+++ b/tests/projects/c++/modules/staticlib/xmake.lua
@@ -0,0 +1,10 @@
+set_languages("c++20")
+
+target("mod")
+ set_kind("static")
+ add_files("src/mod.mpp", "src/mod.cpp")
+
+target("test")
+ set_kind("binary")
+ add_deps("mod")
+ add_files("src/main.cpp")
diff --git a/tests/projects/c++/modules/submodules/src/main.cpp b/tests/projects/c++/modules/submodules/src/main.cpp
new file mode 100644
index 000000000..5ff18701f
--- /dev/null
+++ b/tests/projects/c++/modules/submodules/src/main.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+import math;
+
+int main() {
+
+ std::cout << std::endl;
+
+ std::cout << "add(3, 4): " << add(3, 4) << std::endl;
+ std::cout << "mul(3, 4): " << mul(3, 4) << std::endl;
+}
diff --git a/tests/projects/c++/modules/submodules/src/math.math1.mpp b/tests/projects/c++/modules/submodules/src/math.math1.mpp
new file mode 100644
index 000000000..3e06bf426
--- /dev/null
+++ b/tests/projects/c++/modules/submodules/src/math.math1.mpp
@@ -0,0 +1,5 @@
+export module math.math1;
+
+export int add(int fir, int sec) {
+ return fir + sec;
+}
diff --git a/tests/projects/c++/modules/submodules/src/math.math2.mpp b/tests/projects/c++/modules/submodules/src/math.math2.mpp
new file mode 100644
index 000000000..f6c5381c3
--- /dev/null
+++ b/tests/projects/c++/modules/submodules/src/math.math2.mpp
@@ -0,0 +1,7 @@
+export module math.math2;
+
+export {
+ int mul(int fir, int sec) {
+ return fir * sec;
+ }
+}
diff --git a/tests/projects/c++/modules/submodules/src/math.mpp b/tests/projects/c++/modules/submodules/src/math.mpp
new file mode 100644
index 000000000..0b38b9c08
--- /dev/null
+++ b/tests/projects/c++/modules/submodules/src/math.mpp
@@ -0,0 +1,4 @@
+export module math;
+
+export import math.math1;
+export import math.math2;
diff --git a/tests/projects/c++/modules/submodules/xmake.lua b/tests/projects/c++/modules/submodules/xmake.lua
new file mode 100644
index 000000000..672034947
--- /dev/null
+++ b/tests/projects/c++/modules/submodules/xmake.lua
@@ -0,0 +1,4 @@
+set_languages("c++20")
+target("math")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
diff --git a/tests/projects/c++/protobuf/src/main.cpp b/tests/projects/c++/protobuf/src/main.cpp
index 1e7830c17..dc06458ae 100644
--- a/tests/projects/c++/protobuf/src/main.cpp
+++ b/tests/projects/c++/protobuf/src/main.cpp
@@ -1,10 +1,11 @@
#include <iostream>
#include "test.pb.h"
+#include "subdir/test2.pb.h"
using namespace std;
int main(int argc, char** argv)
{
- cout << "hello world!" << endl;
+ cout << "hello world!" << endl;
return 0;
}
diff --git a/tests/projects/c++/unity_build/src/bar/test4.cpp b/tests/projects/c++/unity_build/src/bar/test4.cpp
new file mode 100644
index 000000000..8fe732964
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/bar/test4.cpp
@@ -0,0 +1,12 @@
+
+// main.cpp
+#include "header.h"
+
+namespace MY_UNITY_ID {
+ int i = 42;
+}
+
+int test4()
+{
+ return MY_UNITY_ID::i;
+}
diff --git a/tests/projects/c++/unity_build/src/bar/test5.cpp b/tests/projects/c++/unity_build/src/bar/test5.cpp
new file mode 100644
index 000000000..afff0b46c
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/bar/test5.cpp
@@ -0,0 +1,13 @@
+
+// main.cpp
+#include "header.h"
+
+namespace MY_UNITY_ID {
+ int i = 42;
+}
+
+int test5()
+{
+ return MY_UNITY_ID::i;
+}
+
diff --git a/tests/projects/c++/unity_build/src/bar/test6.cpp b/tests/projects/c++/unity_build/src/bar/test6.cpp
new file mode 100644
index 000000000..efbd7c6c1
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/bar/test6.cpp
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test6()
+{
+ return 0;
+}
diff --git a/tests/projects/c++/unity_build/src/foo/test.cpp b/tests/projects/c++/unity_build/src/foo/test.cpp
new file mode 100644
index 000000000..e9d6c83d9
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/foo/test.cpp
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test()
+{
+ return 0;
+}
diff --git a/tests/projects/c++/unity_build/src/foo/test2.cpp b/tests/projects/c++/unity_build/src/foo/test2.cpp
new file mode 100644
index 000000000..596359cd2
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/foo/test2.cpp
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test2()
+{
+ return 0;
+}
diff --git a/tests/projects/c++/unity_build/src/header.h b/tests/projects/c++/unity_build/src/header.h
new file mode 100644
index 000000000..affda55ca
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/header.h
@@ -0,0 +1,27 @@
+// header.h
+#ifndef HEADER_H
+#define HEADER_H
+
+#include <algorithm>
+#include <deque>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <set>
+//#include <thread>
+#include <utility>
+#include <vector>
+#include <string>
+#include <queue>
+#include <cstdlib>
+#include <utility>
+#include <exception>
+#include <list>
+#include <stack>
+#include <complex>
+#include <fstream>
+#include <cstdio>
+#include <iomanip>
+
+#endif
+
diff --git a/tests/projects/c++/unity_build/src/header2.h b/tests/projects/c++/unity_build/src/header2.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/header2.h
diff --git a/tests/projects/c++/unity_build/src/main.cpp b/tests/projects/c++/unity_build/src/main.cpp
new file mode 100644
index 000000000..27d41ee50
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/main.cpp
@@ -0,0 +1,8 @@
+#include "header.h"
+
+int main(int argc, char** argv)
+{
+ std::string s("xmake");
+ printf("hello %s!\n", s.c_str());
+ return 0;
+}
diff --git a/tests/projects/c++/unity_build/src/test.c b/tests/projects/c++/unity_build/src/test.c
new file mode 100644
index 000000000..7f0aa2bf4
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/test.c
@@ -0,0 +1,4 @@
+
+void test_c(void)
+{
+}
diff --git a/tests/projects/c++/unity_build/src/test7.cpp b/tests/projects/c++/unity_build/src/test7.cpp
new file mode 100644
index 000000000..24aeff619
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/test7.cpp
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test7()
+{
+ return 0;
+}
diff --git a/tests/projects/c++/unity_build/src/test8.cpp b/tests/projects/c++/unity_build/src/test8.cpp
new file mode 100644
index 000000000..6ad5680a6
--- /dev/null
+++ b/tests/projects/c++/unity_build/src/test8.cpp
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test8()
+{
+ return 0;
+}
diff --git a/tests/projects/c++/unity_build/test.lua b/tests/projects/c++/unity_build/test.lua
new file mode 100644
index 000000000..b76241be2
--- /dev/null
+++ b/tests/projects/c++/unity_build/test.lua
@@ -0,0 +1,6 @@
+-- main entry
+function main(t)
+
+ -- build project
+ t:build()
+end
diff --git a/tests/projects/c++/unity_build/xmake.lua b/tests/projects/c++/unity_build/xmake.lua
new file mode 100644
index 000000000..a881c5c36
--- /dev/null
+++ b/tests/projects/c++/unity_build/xmake.lua
@@ -0,0 +1,9 @@
+target("test")
+ set_kind("binary")
+ add_includedirs("src")
+ add_rules("c++.unity_build", {batchsize = 2, uniqueid = "MY_UNITY_ID"})
+ add_files("src/*.c", "src/*.cpp")
+ add_files("src/foo/*.cpp", {unity_group = "foo"})
+ add_files("src/bar/*.cpp", {unity_group = "bar"})
+
+
diff --git a/tests/projects/c/headeronly/src/foo.h b/tests/projects/c/headeronly/src/foo.h
new file mode 100644
index 000000000..915f44b87
--- /dev/null
+++ b/tests/projects/c/headeronly/src/foo.h
@@ -0,0 +1,9 @@
+/*! calculate add(a, b)
+ *
+ * @param a the first argument
+ * @param b the second argument
+ *
+ * @return the result
+ */
+int add(int a, int b);
+
diff --git a/tests/projects/c/headeronly/test.lua b/tests/projects/c/headeronly/test.lua
new file mode 100644
index 000000000..b76241be2
--- /dev/null
+++ b/tests/projects/c/headeronly/test.lua
@@ -0,0 +1,6 @@
+-- main entry
+function main(t)
+
+ -- build project
+ t:build()
+end
diff --git a/tests/projects/c/headeronly/xmake.lua b/tests/projects/c/headeronly/xmake.lua
new file mode 100644
index 000000000..d43bdceda
--- /dev/null
+++ b/tests/projects/c/headeronly/xmake.lua
@@ -0,0 +1,9 @@
+add_rules("mode.release", "mode.debug")
+
+target("foo")
+ set_kind("headeronly")
+ add_headerfiles("src/foo.h")
+ add_rules("utils.install.cmake_importfiles")
+ add_rules("utils.install.pkgconfig_importfiles")
+
+
diff --git a/tests/projects/c/library_with_cmakelists/.gitignore b/tests/projects/c/library_with_cmakelists/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/c/library_with_cmakelists/foo/CMakeLists.txt b/tests/projects/c/library_with_cmakelists/foo/CMakeLists.txt
new file mode 100644
index 000000000..0745681e0
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/foo/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.13.0)
+project(foo LANGUAGES C CXX ASM)
+
+add_library(foo STATIC "")
+target_sources(foo PRIVATE
+ src/foo.c
+)
+set_target_properties(foo PROPERTIES PUBLIC_HEADER src/foo.h)
+include(GNUInstallDirs)
+install(TARGETS foo
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+)
+
diff --git a/tests/projects/c/library_with_cmakelists/foo/src/foo.c b/tests/projects/c/library_with_cmakelists/foo/src/foo.c
new file mode 100644
index 000000000..08054d059
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/foo/src/foo.c
@@ -0,0 +1,6 @@
+#include "foo.h"
+
+int add(int a, int b)
+{
+ return a + b;
+}
diff --git a/tests/projects/c/library_with_cmakelists/foo/src/foo.h b/tests/projects/c/library_with_cmakelists/foo/src/foo.h
new file mode 100644
index 000000000..6295ab95c
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/foo/src/foo.h
@@ -0,0 +1 @@
+int add(int a, int b);
diff --git a/tests/projects/c/library_with_cmakelists/src/main.c b/tests/projects/c/library_with_cmakelists/src/main.c
new file mode 100644
index 000000000..1e52e7a81
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/src/main.c
@@ -0,0 +1,8 @@
+#include "foo.h"
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+ printf("add(1, 2) = %d\n", add(1, 2));
+ return 0;
+}
diff --git a/tests/projects/c/library_with_cmakelists/test.lua b/tests/projects/c/library_with_cmakelists/test.lua
new file mode 100644
index 000000000..3c28e0c3e
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/test.lua
@@ -0,0 +1,13 @@
+-- main entry
+function main(t)
+
+ -- freebsd ci is slower
+ if is_host("bsd") then
+ return
+ end
+
+ -- only for x86/x64, because it will take too long time on ci with arm/mips
+ if os.subarch():startswith("x") or os.subarch() == "i386" then
+ t:build()
+ end
+end
diff --git a/tests/projects/c/library_with_cmakelists/xmake.lua b/tests/projects/c/library_with_cmakelists/xmake.lua
new file mode 100644
index 000000000..e5646c372
--- /dev/null
+++ b/tests/projects/c/library_with_cmakelists/xmake.lua
@@ -0,0 +1,23 @@
+add_rules("mode.debug", "mode.release")
+
+package("foo")
+ add_deps("cmake")
+ set_sourcedir(path.join(os.scriptdir(), "foo"))
+ on_install(function (package)
+ local configs = {}
+ table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))
+ table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
+ import("package.tools.cmake").install(package, configs)
+ end)
+ on_test(function (package)
+ assert(package:has_cfuncs("add", {includes = "foo.h"}))
+ end)
+package_end()
+
+add_requires("foo")
+
+target("demo")
+ set_kind("binary")
+ add_files("src/main.c")
+ add_packages("foo")
+
diff --git a/tests/projects/c/unity_build/src/bar/test4.c b/tests/projects/c/unity_build/src/bar/test4.c
new file mode 100644
index 000000000..a92803eb7
--- /dev/null
+++ b/tests/projects/c/unity_build/src/bar/test4.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test4()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/bar/test5.c b/tests/projects/c/unity_build/src/bar/test5.c
new file mode 100644
index 000000000..2a3e7066c
--- /dev/null
+++ b/tests/projects/c/unity_build/src/bar/test5.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test5()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/foo/test1.c b/tests/projects/c/unity_build/src/foo/test1.c
new file mode 100644
index 000000000..e9d6c83d9
--- /dev/null
+++ b/tests/projects/c/unity_build/src/foo/test1.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/foo/test2.c b/tests/projects/c/unity_build/src/foo/test2.c
new file mode 100644
index 000000000..b4ce69b0f
--- /dev/null
+++ b/tests/projects/c/unity_build/src/foo/test2.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test3()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/header.h b/tests/projects/c/unity_build/src/header.h
new file mode 100644
index 000000000..29bfc5870
--- /dev/null
+++ b/tests/projects/c/unity_build/src/header.h
@@ -0,0 +1,10 @@
+// header.h
+#ifndef HEADER_H
+#define HEADER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#endif
+
diff --git a/tests/projects/c/unity_build/src/main.c b/tests/projects/c/unity_build/src/main.c
new file mode 100644
index 000000000..f0408cdf8
--- /dev/null
+++ b/tests/projects/c/unity_build/src/main.c
@@ -0,0 +1,7 @@
+#include "header.h"
+
+int main(int argc, char** argv)
+{
+ printf("hello xmake!\n");
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/test.cpp b/tests/projects/c/unity_build/src/test.cpp
new file mode 100644
index 000000000..1cedddad9
--- /dev/null
+++ b/tests/projects/c/unity_build/src/test.cpp
@@ -0,0 +1,4 @@
+int test_cpp()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/test2.c b/tests/projects/c/unity_build/src/test2.c
new file mode 100644
index 000000000..596359cd2
--- /dev/null
+++ b/tests/projects/c/unity_build/src/test2.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test2()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/test6.c b/tests/projects/c/unity_build/src/test6.c
new file mode 100644
index 000000000..efbd7c6c1
--- /dev/null
+++ b/tests/projects/c/unity_build/src/test6.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test6()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/test7.c b/tests/projects/c/unity_build/src/test7.c
new file mode 100644
index 000000000..24aeff619
--- /dev/null
+++ b/tests/projects/c/unity_build/src/test7.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test7()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/src/test8.c b/tests/projects/c/unity_build/src/test8.c
new file mode 100644
index 000000000..6ad5680a6
--- /dev/null
+++ b/tests/projects/c/unity_build/src/test8.c
@@ -0,0 +1,8 @@
+
+// main.cpp
+#include "header.h"
+
+int test8()
+{
+ return 0;
+}
diff --git a/tests/projects/c/unity_build/test.lua b/tests/projects/c/unity_build/test.lua
new file mode 100644
index 000000000..b76241be2
--- /dev/null
+++ b/tests/projects/c/unity_build/test.lua
@@ -0,0 +1,6 @@
+-- main entry
+function main(t)
+
+ -- build project
+ t:build()
+end
diff --git a/tests/projects/c/unity_build/xmake.lua b/tests/projects/c/unity_build/xmake.lua
new file mode 100644
index 000000000..89166a312
--- /dev/null
+++ b/tests/projects/c/unity_build/xmake.lua
@@ -0,0 +1,8 @@
+target("test")
+ set_kind("binary")
+ add_includedirs("src")
+ add_rules("c.unity_build", {batchsize = 2})
+ add_files("src/*.c", "src/*.cpp")
+ add_files("src/foo/*.c", {unity_group = "foo"})
+ add_files("src/bar/*.c", {unity_group = "bar"})
+
diff --git a/tests/projects/embed/mdk/hello/src/foo/foo.c b/tests/projects/embed/mdk/hello/src/foo/foo.c
new file mode 100644
index 000000000..e51afb553
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/foo/foo.c
@@ -0,0 +1,4 @@
+int foo(int x)
+{
+ return x;
+}
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/ARMCM3.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/ARMCM3.h
new file mode 100644
index 000000000..44c0c23f4
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/ARMCM3.h
@@ -0,0 +1,126 @@
+/**************************************************************************//**
+ * @file ARMCM3.h
+ * @brief CMSIS Core Peripheral Access Layer Header File for
+ * ARMCM3 Device
+ * @version V5.3.1
+ * @date 09. July 2018
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ARMCM3_H
+#define ARMCM3_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ------------------------- Interrupt Number Definition ------------------------ */
+
+typedef enum IRQn
+{
+/* ------------------- Processor Exceptions Numbers ----------------------------- */
+ NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */
+ HardFault_IRQn = -13, /* 3 HardFault Interrupt */
+ MemoryManagement_IRQn = -12, /* 4 Memory Management Interrupt */
+ BusFault_IRQn = -11, /* 5 Bus Fault Interrupt */
+ UsageFault_IRQn = -10, /* 6 Usage Fault Interrupt */
+ SVCall_IRQn = -5, /* 11 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /* 12 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /* 14 Pend SV Interrupt */
+ SysTick_IRQn = -1, /* 15 System Tick Interrupt */
+
+/* ------------------- Processor Interrupt Numbers ------------------------------ */
+ Interrupt0_IRQn = 0,
+ Interrupt1_IRQn = 1,
+ Interrupt2_IRQn = 2,
+ Interrupt3_IRQn = 3,
+ Interrupt4_IRQn = 4,
+ Interrupt5_IRQn = 5,
+ Interrupt6_IRQn = 6,
+ Interrupt7_IRQn = 7,
+ Interrupt8_IRQn = 8,
+ Interrupt9_IRQn = 9
+ /* Interrupts 10 .. 224 are left out */
+} IRQn_Type;
+
+
+/* ================================================================================ */
+/* ================ Processor and Core Peripheral Section ================ */
+/* ================================================================================ */
+
+/* ------- Start of section using anonymous unions and disabling warnings ------- */
+#if defined (__CC_ARM)
+ #pragma push
+ #pragma anon_unions
+#elif defined (__ICCARM__)
+ #pragma language=extended
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wc11-extensions"
+ #pragma clang diagnostic ignored "-Wreserved-id-macro"
+#elif defined (__GNUC__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TMS470__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TASKING__)
+ #pragma warning 586
+#elif defined (__CSMC__)
+ /* anonymous unions are enabled by default */
+#else
+ #warning Not supported compiler type
+#endif
+
+
+/* -------- Configuration of Core Peripherals ----------------------------------- */
+#define __CM3_REV 0x0201U /* Core revision r2p1 */
+#define __MPU_PRESENT 1U /* MPU present */
+#define __VTOR_PRESENT 1U /* VTOR present */
+#define __NVIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */
+
+#include "core_cm3.h" /* Processor and core peripherals */
+#include "system_ARMCM3.h" /* System Header */
+
+
+/* -------- End of section using anonymous unions and disabling warnings -------- */
+#if defined (__CC_ARM)
+ #pragma pop
+#elif defined (__ICCARM__)
+ /* leave anonymous unions enabled */
+#elif (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+ #pragma clang diagnostic pop
+#elif defined (__GNUC__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TMS470__)
+ /* anonymous unions are enabled by default */
+#elif defined (__TASKING__)
+ #pragma warning restore
+#elif defined (__CSMC__)
+ /* anonymous unions are enabled by default */
+#else
+ #warning Not supported compiler type
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ARMCM3_H */
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armcc.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armcc.h
new file mode 100644
index 000000000..a955d4713
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armcc.h
@@ -0,0 +1,888 @@
+/**************************************************************************//**
+ * @file cmsis_armcc.h
+ * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
+ * @version V5.3.2
+ * @date 27. May 2021
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+ #error "Please use Arm Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* CMSIS compiler control architecture macros */
+#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
+ (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
+ #define __ARM_ARCH_6M__ 1
+#endif
+
+#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
+ #define __ARM_ARCH_7M__ 1
+#endif
+
+#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
+ #define __ARM_ARCH_7EM__ 1
+#endif
+
+ /* __ARM_ARCH_8M_BASE__ not applicable */
+ /* __ARM_ARCH_8M_MAIN__ not applicable */
+ /* __ARM_ARCH_8_1M_MAIN__ not applicable */
+
+/* CMSIS compiler control DSP macros */
+#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+ #define __ARM_FEATURE_DSP 1
+#endif
+
+/* CMSIS compiler specific defines */
+#ifndef __ASM
+ #define __ASM __asm
+#endif
+#ifndef __INLINE
+ #define __INLINE __inline
+#endif
+#ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static __inline
+#endif
+#ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE static __forceinline
+#endif
+#ifndef __NO_RETURN
+ #define __NO_RETURN __declspec(noreturn)
+#endif
+#ifndef __USED
+ #define __USED __attribute__((used))
+#endif
+#ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+#endif
+#ifndef __PACKED
+ #define __PACKED __attribute__((packed))
+#endif
+#ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT __packed struct
+#endif
+#ifndef __PACKED_UNION
+ #define __PACKED_UNION __packed union
+#endif
+#ifndef __UNALIGNED_UINT32 /* deprecated */
+ #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
+#endif
+#ifndef __UNALIGNED_UINT16_WRITE
+ #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
+#endif
+#ifndef __UNALIGNED_UINT16_READ
+ #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
+#endif
+#ifndef __UNALIGNED_UINT32_WRITE
+ #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
+#endif
+#ifndef __UNALIGNED_UINT32_READ
+ #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
+#endif
+#ifndef __ALIGNED
+ #define __ALIGNED(x) __attribute__((aligned(x)))
+#endif
+#ifndef __RESTRICT
+ #define __RESTRICT __restrict
+#endif
+#ifndef __COMPILER_BARRIER
+ #define __COMPILER_BARRIER() __memory_changed()
+#endif
+
+/* ######################### Startup and Lowlevel Init ######################## */
+
+#ifndef __PROGRAM_START
+#define __PROGRAM_START __main
+#endif
+
+#ifndef __INITIAL_SP
+#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit
+#endif
+
+#ifndef __STACK_LIMIT
+#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base
+#endif
+
+#ifndef __VECTOR_TABLE
+#define __VECTOR_TABLE __Vectors
+#endif
+
+#ifndef __VECTOR_TABLE_ATTRIBUTE
+#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET")))
+#endif
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __nop
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI __wfi
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __sev
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+#define __ISB() __isb(0xF)
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() __dsb(0xF)
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() __dmb(0xF)
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __rev
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] op1 Value to rotate
+ \param [in] op2 Number of Bits to rotate
+ \return Rotated value
+ */
+#define __ROR __ror
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __breakpoint(value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+ #define __RBIT __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+ uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value != 0U; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+ return result;
+}
+#endif
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __clz
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
+#else
+ #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
+#else
+ #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
+#else
+ #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXB(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXH(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXW(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __clrex
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __ssat
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __usat
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+ rrx r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRBT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRHT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRT(value, ptr) __strt(value, ptr)
+
+#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
+{
+ if ((sat >= 1U) && (sat <= 32U))
+ {
+ const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
+ const int32_t min = -1 - max ;
+ if (val > max)
+ {
+ return max;
+ }
+ else if (val < min)
+ {
+ return min;
+ }
+ }
+ return val;
+}
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
+{
+ if (sat <= 31U)
+ {
+ const uint32_t max = ((1U << sat) - 1U);
+ if (val > (int32_t)max)
+ {
+ return max;
+ }
+ else if (val < 0)
+ {
+ return 0U;
+ }
+ }
+ return (uint32_t)val;
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
+ Can only be executed in Privileged modes.
+ */
+/* intrinsic void __enable_irq(); */
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
+ Can only be executed in Privileged modes.
+ */
+/* intrinsic void __disable_irq(); */
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+ __ISB();
+}
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ register uint32_t __regIPSR __ASM("ipsr");
+ return(__regIPSR);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+ register uint32_t __regAPSR __ASM("apsr");
+ return(__regAPSR);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ register uint32_t __regXPSR __ASM("xpsr");
+ return(__regXPSR);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ return(__regProcessStackPointer);
+}
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ __regProcessStackPointer = topOfProcStack;
+}
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ return(__regMainStackPointer);
+}
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ __regMainStackPointer = topOfMainStack;
+}
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK.
+ Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq __enable_fiq
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting special-purpose register FAULTMASK.
+ Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq __disable_fiq
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+ register uint32_t __regBasePriMax __ASM("basepri_max");
+ __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & (uint32_t)1U);
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+
+
+/**
+ \brief Get FPSCR
+ \details Returns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+ register uint32_t __regfpscr __ASM("fpscr");
+ return(__regfpscr);
+#else
+ return(0U);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+ register uint32_t __regfpscr __ASM("fpscr");
+ __regfpscr = (fpscr);
+#else
+ (void)fpscr;
+#endif
+}
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
+
+#define __SADD8 __sadd8
+#define __QADD8 __qadd8
+#define __SHADD8 __shadd8
+#define __UADD8 __uadd8
+#define __UQADD8 __uqadd8
+#define __UHADD8 __uhadd8
+#define __SSUB8 __ssub8
+#define __QSUB8 __qsub8
+#define __SHSUB8 __shsub8
+#define __USUB8 __usub8
+#define __UQSUB8 __uqsub8
+#define __UHSUB8 __uhsub8
+#define __SADD16 __sadd16
+#define __QADD16 __qadd16
+#define __SHADD16 __shadd16
+#define __UADD16 __uadd16
+#define __UQADD16 __uqadd16
+#define __UHADD16 __uhadd16
+#define __SSUB16 __ssub16
+#define __QSUB16 __qsub16
+#define __SHSUB16 __shsub16
+#define __USUB16 __usub16
+#define __UQSUB16 __uqsub16
+#define __UHSUB16 __uhsub16
+#define __SASX __sasx
+#define __QASX __qasx
+#define __SHASX __shasx
+#define __UASX __uasx
+#define __UQASX __uqasx
+#define __UHASX __uhasx
+#define __SSAX __ssax
+#define __QSAX __qsax
+#define __SHSAX __shsax
+#define __USAX __usax
+#define __UQSAX __uqsax
+#define __UHSAX __uhsax
+#define __USAD8 __usad8
+#define __USADA8 __usada8
+#define __SSAT16 __ssat16
+#define __USAT16 __usat16
+#define __UXTB16 __uxtb16
+#define __UXTAB16 __uxtab16
+#define __SXTB16 __sxtb16
+#define __SXTAB16 __sxtab16
+#define __SMUAD __smuad
+#define __SMUADX __smuadx
+#define __SMLAD __smlad
+#define __SMLADX __smladx
+#define __SMLALD __smlald
+#define __SMLALDX __smlaldx
+#define __SMUSD __smusd
+#define __SMUSDX __smusdx
+#define __SMLSD __smlsd
+#define __SMLSDX __smlsdx
+#define __SMLSLD __smlsld
+#define __SMLSLDX __smlsldx
+#define __SEL __sel
+#define __QADD __qadd
+#define __QSUB __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+ ((int64_t)(ARG3) << 32U) ) >> 32U))
+
+#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2))
+
+#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3))
+
+#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_H */
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armclang.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armclang.h
new file mode 100644
index 000000000..691141774
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_armclang.h
@@ -0,0 +1,1503 @@
+/**************************************************************************//**
+ * @file cmsis_armclang.h
+ * @brief CMSIS compiler armclang (Arm Compiler 6) header file
+ * @version V5.4.3
+ * @date 27. May 2021
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */
+
+#ifndef __CMSIS_ARMCLANG_H
+#define __CMSIS_ARMCLANG_H
+
+#pragma clang system_header /* treat file as system include file */
+
+/* CMSIS compiler specific defines */
+#ifndef __ASM
+ #define __ASM __asm
+#endif
+#ifndef __INLINE
+ #define __INLINE __inline
+#endif
+#ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static __inline
+#endif
+#ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
+#endif
+#ifndef __NO_RETURN
+ #define __NO_RETURN __attribute__((__noreturn__))
+#endif
+#ifndef __USED
+ #define __USED __attribute__((used))
+#endif
+#ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+#endif
+#ifndef __PACKED
+ #define __PACKED __attribute__((packed, aligned(1)))
+#endif
+#ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
+#endif
+#ifndef __PACKED_UNION
+ #define __PACKED_UNION union __attribute__((packed, aligned(1)))
+#endif
+#ifndef __UNALIGNED_UINT32 /* deprecated */
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wpacked"
+/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */
+ struct __attribute__((packed)) T_UINT32 { uint32_t v; };
+ #pragma clang diagnostic pop
+ #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
+#endif
+#ifndef __UNALIGNED_UINT16_WRITE
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wpacked"
+/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
+ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+ #pragma clang diagnostic pop
+ #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+#endif
+#ifndef __UNALIGNED_UINT16_READ
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wpacked"
+/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
+ __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+ #pragma clang diagnostic pop
+ #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+#endif
+#ifndef __UNALIGNED_UINT32_WRITE
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wpacked"
+/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
+ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+ #pragma clang diagnostic pop
+ #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+#endif
+#ifndef __UNALIGNED_UINT32_READ
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wpacked"
+/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */
+ __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+ #pragma clang diagnostic pop
+ #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+#endif
+#ifndef __ALIGNED
+ #define __ALIGNED(x) __attribute__((aligned(x)))
+#endif
+#ifndef __RESTRICT
+ #define __RESTRICT __restrict
+#endif
+#ifndef __COMPILER_BARRIER
+ #define __COMPILER_BARRIER() __ASM volatile("":::"memory")
+#endif
+
+/* ######################### Startup and Lowlevel Init ######################## */
+
+#ifndef __PROGRAM_START
+#define __PROGRAM_START __main
+#endif
+
+#ifndef __INITIAL_SP
+#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit
+#endif
+
+#ifndef __STACK_LIMIT
+#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base
+#endif
+
+#ifndef __VECTOR_TABLE
+#define __VECTOR_TABLE __Vectors
+#endif
+
+#ifndef __VECTOR_TABLE_ATTRIBUTE
+#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET")))
+#endif
+
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+#ifndef __STACK_SEAL
+#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base
+#endif
+
+#ifndef __TZ_STACK_SEAL_SIZE
+#define __TZ_STACK_SEAL_SIZE 8U
+#endif
+
+#ifndef __TZ_STACK_SEAL_VALUE
+#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL
+#endif
+
+
+__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) {
+ *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE;
+}
+#endif
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_RW_REG(r) "+l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_RW_REG(r) "+r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __builtin_arm_nop
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI __builtin_arm_wfi
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __builtin_arm_wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __builtin_arm_sev
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+#define __ISB() __builtin_arm_isb(0xF)
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() __builtin_arm_dsb(0xF)
+
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() __builtin_arm_dmb(0xF)
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV(value) __builtin_bswap32(value)
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV16(value) __ROR(__REV(value), 16)
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REVSH(value) (int16_t)__builtin_bswap16(value)
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] op1 Value to rotate
+ \param [in] op2 Number of Bits to rotate
+ \return Rotated value
+ */
+__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+ op2 %= 32U;
+ if (op2 == 0U)
+ {
+ return op1;
+ }
+ return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __ASM volatile ("bkpt "#value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __RBIT __builtin_arm_rbit
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value)
+{
+ /* Even though __builtin_clz produces a CLZ instruction on ARM, formally
+ __builtin_clz(0) is undefined behaviour, so handle this case specially.
+ This guarantees ARM-compatible results if happening to compile on a non-ARM
+ target, and ensures the compiler doesn't decide to activate any
+ optimisations using the logic "value was passed to __builtin_clz, so it
+ is non-zero".
+ ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a
+ single CLZ instruction.
+ */
+ if (value == 0U)
+ {
+ return 32U;
+ }
+ return __builtin_clz(value);
+}
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDREXB (uint8_t)__builtin_arm_ldrex
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDREXH (uint16_t)__builtin_arm_ldrex
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDREXW (uint32_t)__builtin_arm_ldrex
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXB (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXH (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXW (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __builtin_arm_clrex
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __builtin_arm_ssat
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __builtin_arm_usat
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return(result);
+}
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
+}
+
+#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
+{
+ if ((sat >= 1U) && (sat <= 32U))
+ {
+ const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
+ const int32_t min = -1 - max ;
+ if (val > max)
+ {
+ return max;
+ }
+ else if (val < min)
+ {
+ return min;
+ }
+ }
+ return val;
+}
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
+{
+ if (sat <= 31U)
+ {
+ const uint32_t max = ((1U << sat) - 1U);
+ if (val > (int32_t)max)
+ {
+ return max;
+ }
+ else if (val < 0)
+ {
+ return 0U;
+ }
+ }
+ return (uint32_t)val;
+}
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */
+
+
+#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
+
+/**
+ \brief Load-Acquire (8 bit)
+ \details Executes a LDAB instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
+ return ((uint8_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (16 bit)
+ \details Executes a LDAH instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
+ return ((uint16_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (32 bit)
+ \details Executes a LDA instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" );
+ return(result);
+}
+
+
+/**
+ \brief Store-Release (8 bit)
+ \details Executes a STLB instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
+}
+
+
+/**
+ \brief Store-Release (16 bit)
+ \details Executes a STLH instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
+}
+
+
+/**
+ \brief Store-Release (32 bit)
+ \details Executes a STL instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" );
+}
+
+
+/**
+ \brief Load-Acquire Exclusive (8 bit)
+ \details Executes a LDAB exclusive instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDAEXB (uint8_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Load-Acquire Exclusive (16 bit)
+ \details Executes a LDAH exclusive instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDAEXH (uint16_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Load-Acquire Exclusive (32 bit)
+ \details Executes a LDA exclusive instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDAEX (uint32_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Store-Release Exclusive (8 bit)
+ \details Executes a STLB exclusive instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STLEXB (uint32_t)__builtin_arm_stlex
+
+
+/**
+ \brief Store-Release Exclusive (16 bit)
+ \details Executes a STLH exclusive instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STLEXH (uint32_t)__builtin_arm_stlex
+
+
+/**
+ \brief Store-Release Exclusive (32 bit)
+ \details Executes a STL exclusive instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STLEX (uint32_t)__builtin_arm_stlex
+
+#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
+ Can only be executed in Privileged modes.
+ */
+#ifndef __ARM_COMPAT_H
+__STATIC_FORCEINLINE void __enable_irq(void)
+{
+ __ASM volatile ("cpsie i" : : : "memory");
+}
+#endif
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting special-purpose register PRIMASK.
+ Can only be executed in Privileged modes.
+ */
+#ifndef __ARM_COMPAT_H
+__STATIC_FORCEINLINE void __disable_irq(void)
+{
+ __ASM volatile ("cpsid i" : : : "memory");
+}
+#endif
+
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Control Register (non-secure)
+ \details Returns the content of the non-secure Control Register when in secure mode.
+ \return non-secure Control Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+ __ISB();
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Control Register (non-secure)
+ \details Writes the given value to the non-secure Control Register when in secure state.
+ \param [in] control Control Register value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control)
+{
+ __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
+ __ISB();
+}
+#endif
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_PSP(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, psp" : "=r" (result) );
+ return(result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Process Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
+ \return PSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : );
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_MSP(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, msp" : "=r" (result) );
+ return(result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Main Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
+ \return MSP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Main Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : );
+}
+#endif
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state.
+ \return SP Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, sp_ns" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state.
+ \param [in] topOfStack Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack)
+{
+ __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : );
+}
+#endif
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Priority Mask (non-secure)
+ \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
+ \return Priority Mask value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Priority Mask (non-secure)
+ \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
+}
+#endif
+
+
+#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK.
+ Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __enable_fault_irq(void)
+{
+ __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting special-purpose register FAULTMASK.
+ Can only be executed in Privileged modes.
+ */
+__STATIC_FORCEINLINE void __disable_fault_irq(void)
+{
+ __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+ return(result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Base Priority (non-secure)
+ \details Returns the current value of the non-secure Base Priority register when in secure state.
+ \return Base Priority register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Base Priority (non-secure)
+ \details Assigns the given value to the non-secure Base Priority register when in secure state.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri)
+{
+ __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory");
+}
+#endif
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+ __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory");
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Fault Mask (non-secure)
+ \details Returns the current value of the non-secure Fault Mask register when in secure state.
+ \return Fault Mask register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Fault Mask (non-secure)
+ \details Assigns the given value to the non-secure Fault Mask register when in secure state.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
+}
+#endif
+
+#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
+ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
+ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */
+
+
+#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
+
+/**
+ \brief Get Process Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always in non-secure
+ mode.
+
+ \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
+ \return PSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile ("MRS %0, psplim" : "=r" (result) );
+ return result;
+#endif
+}
+
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Process Stack Pointer Limit (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always in non-secure
+ mode.
+
+ \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \return PSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) )
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
+ return result;
+#endif
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored in non-secure
+ mode.
+
+ \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ (void)ProcStackPtrLimit;
+#else
+ __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
+#endif
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored in non-secure
+ mode.
+
+ \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) )
+ // without main extensions, the non-secure PSPLIM is RAZ/WI
+ (void)ProcStackPtrLimit;
+#else
+ __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
+#endif
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always.
+
+ \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
+ \return MSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile ("MRS %0, msplim" : "=r" (result) );
+ return result;
+#endif
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Get Main Stack Pointer Limit (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence zero is returned always.
+
+ \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
+ \return MSPLIM Register value
+ */
+__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) )
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ return 0U;
+#else
+ uint32_t result;
+ __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
+ return result;
+#endif
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer Limit
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored.
+
+ \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
+ \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
+ */
+__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \
+ (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ (void)MainStackPtrLimit;
+#else
+ __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
+#endif
+}
+
+
+#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
+/**
+ \brief Set Main Stack Pointer Limit (non-secure)
+ Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
+ Stack Pointer Limit register hence the write is silently ignored.
+
+ \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
+ \param [in] MainStackPtrLimit Main Stack Pointer value to set
+ */
+__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
+{
+#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) )
+ // without main extensions, the non-secure MSPLIM is RAZ/WI
+ (void)MainStackPtrLimit;
+#else
+ __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
+#endif
+}
+#endif
+
+#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
+ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \
+ (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */
+
+/**
+ \brief Get FPSCR
+ \details Returns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr
+#else
+#define __get_FPSCR() ((uint32_t)0U)
+#endif
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
+ (defined (__FPU_USED ) && (__FPU_USED == 1U)) )
+#define __set_FPSCR __builtin_arm_set_fpscr
+#else
+#define __set_FPSCR(x) ((void)(x))
+#endif
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
+
+#define __SADD8 __builtin_arm_sadd8
+#define __QADD8 __builtin_arm_qadd8
+#define __SHADD8 __builtin_arm_shadd8
+#define __UADD8 __builtin_arm_uadd8
+#define __UQADD8 __builtin_arm_uqadd8
+#define __UHADD8 __builtin_arm_uhadd8
+#define __SSUB8 __builtin_arm_ssub8
+#define __QSUB8 __builtin_arm_qsub8
+#define __SHSUB8 __builtin_arm_shsub8
+#define __USUB8 __builtin_arm_usub8
+#define __UQSUB8 __builtin_arm_uqsub8
+#define __UHSUB8 __builtin_arm_uhsub8
+#define __SADD16 __builtin_arm_sadd16
+#define __QADD16 __builtin_arm_qadd16
+#define __SHADD16 __builtin_arm_shadd16
+#define __UADD16 __builtin_arm_uadd16
+#define __UQADD16 __builtin_arm_uqadd16
+#define __UHADD16 __builtin_arm_uhadd16
+#define __SSUB16 __builtin_arm_ssub16
+#define __QSUB16 __builtin_arm_qsub16
+#define __SHSUB16 __builtin_arm_shsub16
+#define __USUB16 __builtin_arm_usub16
+#define __UQSUB16 __builtin_arm_uqsub16
+#define __UHSUB16 __builtin_arm_uhsub16
+#define __SASX __builtin_arm_sasx
+#define __QASX __builtin_arm_qasx
+#define __SHASX __builtin_arm_shasx
+#define __UASX __builtin_arm_uasx
+#define __UQASX __builtin_arm_uqasx
+#define __UHASX __builtin_arm_uhasx
+#define __SSAX __builtin_arm_ssax
+#define __QSAX __builtin_arm_qsax
+#define __SHSAX __builtin_arm_shsax
+#define __USAX __builtin_arm_usax
+#define __UQSAX __builtin_arm_uqsax
+#define __UHSAX __builtin_arm_uhsax
+#define __USAD8 __builtin_arm_usad8
+#define __USADA8 __builtin_arm_usada8
+#define __SSAT16 __builtin_arm_ssat16
+#define __USAT16 __builtin_arm_usat16
+#define __UXTB16 __builtin_arm_uxtb16
+#define __UXTAB16 __builtin_arm_uxtab16
+#define __SXTB16 __builtin_arm_sxtb16
+#define __SXTAB16 __builtin_arm_sxtab16
+#define __SMUAD __builtin_arm_smuad
+#define __SMUADX __builtin_arm_smuadx
+#define __SMLAD __builtin_arm_smlad
+#define __SMLADX __builtin_arm_smladx
+#define __SMLALD __builtin_arm_smlald
+#define __SMLALDX __builtin_arm_smlaldx
+#define __SMUSD __builtin_arm_smusd
+#define __SMUSDX __builtin_arm_smusdx
+#define __SMLSD __builtin_arm_smlsd
+#define __SMLSDX __builtin_arm_smlsdx
+#define __SMLSLD __builtin_arm_smlsld
+#define __SMLSLDX __builtin_arm_smlsldx
+#define __SEL __builtin_arm_sel
+#define __QADD __builtin_arm_qadd
+#define __QSUB __builtin_arm_qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2))
+
+#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3))
+
+__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__ARM_FEATURE_DSP == 1) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCLANG_H */
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_compiler.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_compiler.h
new file mode 100644
index 000000000..adbf296f1
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_compiler.h
@@ -0,0 +1,283 @@
+/**************************************************************************//**
+ * @file cmsis_compiler.h
+ * @brief CMSIS compiler generic header file
+ * @version V5.1.0
+ * @date 09. October 2018
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMSIS_COMPILER_H
+#define __CMSIS_COMPILER_H
+
+#include <stdint.h>
+
+/*
+ * Arm Compiler 4/5
+ */
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+
+/*
+ * Arm Compiler 6.6 LTM (armclang)
+ */
+#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
+ #include "cmsis_armclang_ltm.h"
+
+ /*
+ * Arm Compiler above 6.10.1 (armclang)
+ */
+#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
+ #include "cmsis_armclang.h"
+
+
+/*
+ * GNU Compiler
+ */
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+
+/*
+ * IAR Compiler
+ */
+#elif defined ( __ICCARM__ )
+ #include <cmsis_iccarm.h>
+
+
+/*
+ * TI Arm Compiler
+ */
+#elif defined ( __TI_ARM__ )
+ #include <cmsis_ccs.h>
+
+ #ifndef __ASM
+ #define __ASM __asm
+ #endif
+ #ifndef __INLINE
+ #define __INLINE inline
+ #endif
+ #ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static inline
+ #endif
+ #ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE __STATIC_INLINE
+ #endif
+ #ifndef __NO_RETURN
+ #define __NO_RETURN __attribute__((noreturn))
+ #endif
+ #ifndef __USED
+ #define __USED __attribute__((used))
+ #endif
+ #ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+ #endif
+ #ifndef __PACKED
+ #define __PACKED __attribute__((packed))
+ #endif
+ #ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT struct __attribute__((packed))
+ #endif
+ #ifndef __PACKED_UNION
+ #define __PACKED_UNION union __attribute__((packed))
+ #endif
+ #ifndef __UNALIGNED_UINT32 /* deprecated */
+ struct __attribute__((packed)) T_UINT32 { uint32_t v; };
+ #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
+ #endif
+ #ifndef __UNALIGNED_UINT16_WRITE
+ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+ #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
+ #endif
+ #ifndef __UNALIGNED_UINT16_READ
+ __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+ #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+ #endif
+ #ifndef __UNALIGNED_UINT32_WRITE
+ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+ #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+ #endif
+ #ifndef __UNALIGNED_UINT32_READ
+ __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+ #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+ #endif
+ #ifndef __ALIGNED
+ #define __ALIGNED(x) __attribute__((aligned(x)))
+ #endif
+ #ifndef __RESTRICT
+ #define __RESTRICT __restrict
+ #endif
+ #ifndef __COMPILER_BARRIER
+ #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
+ #define __COMPILER_BARRIER() (void)0
+ #endif
+
+
+/*
+ * TASKING Compiler
+ */
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+ #ifndef __ASM
+ #define __ASM __asm
+ #endif
+ #ifndef __INLINE
+ #define __INLINE inline
+ #endif
+ #ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static inline
+ #endif
+ #ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE __STATIC_INLINE
+ #endif
+ #ifndef __NO_RETURN
+ #define __NO_RETURN __attribute__((noreturn))
+ #endif
+ #ifndef __USED
+ #define __USED __attribute__((used))
+ #endif
+ #ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+ #endif
+ #ifndef __PACKED
+ #define __PACKED __packed__
+ #endif
+ #ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT struct __packed__
+ #endif
+ #ifndef __PACKED_UNION
+ #define __PACKED_UNION union __packed__
+ #endif
+ #ifndef __UNALIGNED_UINT32 /* deprecated */
+ struct __packed__ T_UINT32 { uint32_t v; };
+ #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
+ #endif
+ #ifndef __UNALIGNED_UINT16_WRITE
+ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+ #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+ #endif
+ #ifndef __UNALIGNED_UINT16_READ
+ __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+ #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+ #endif
+ #ifndef __UNALIGNED_UINT32_WRITE
+ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+ #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+ #endif
+ #ifndef __UNALIGNED_UINT32_READ
+ __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+ #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+ #endif
+ #ifndef __ALIGNED
+ #define __ALIGNED(x) __align(x)
+ #endif
+ #ifndef __RESTRICT
+ #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
+ #define __RESTRICT
+ #endif
+ #ifndef __COMPILER_BARRIER
+ #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
+ #define __COMPILER_BARRIER() (void)0
+ #endif
+
+
+/*
+ * COSMIC Compiler
+ */
+#elif defined ( __CSMC__ )
+ #include <cmsis_csm.h>
+
+ #ifndef __ASM
+ #define __ASM _asm
+ #endif
+ #ifndef __INLINE
+ #define __INLINE inline
+ #endif
+ #ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static inline
+ #endif
+ #ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE __STATIC_INLINE
+ #endif
+ #ifndef __NO_RETURN
+ // NO RETURN is automatically detected hence no warning here
+ #define __NO_RETURN
+ #endif
+ #ifndef __USED
+ #warning No compiler specific solution for __USED. __USED is ignored.
+ #define __USED
+ #endif
+ #ifndef __WEAK
+ #define __WEAK __weak
+ #endif
+ #ifndef __PACKED
+ #define __PACKED @packed
+ #endif
+ #ifndef __PACKED_STRUCT
+ #define __PACKED_STRUCT @packed struct
+ #endif
+ #ifndef __PACKED_UNION
+ #define __PACKED_UNION @packed union
+ #endif
+ #ifndef __UNALIGNED_UINT32 /* deprecated */
+ @packed struct T_UINT32 { uint32_t v; };
+ #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
+ #endif
+ #ifndef __UNALIGNED_UINT16_WRITE
+ __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
+ #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
+ #endif
+ #ifndef __UNALIGNED_UINT16_READ
+ __PACKED_STRUCT T_UINT16_READ { uint16_t v; };
+ #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
+ #endif
+ #ifndef __UNALIGNED_UINT32_WRITE
+ __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
+ #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
+ #endif
+ #ifndef __UNALIGNED_UINT32_READ
+ __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
+ #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
+ #endif
+ #ifndef __ALIGNED
+ #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
+ #define __ALIGNED(x)
+ #endif
+ #ifndef __RESTRICT
+ #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
+ #define __RESTRICT
+ #endif
+ #ifndef __COMPILER_BARRIER
+ #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
+ #define __COMPILER_BARRIER() (void)0
+ #endif
+
+
+#else
+ #error Unknown compiler.
+#endif
+
+
+#endif /* __CMSIS_COMPILER_H */
+
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_version.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_version.h
new file mode 100644
index 000000000..2f048e455
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/cmsis_version.h
@@ -0,0 +1,39 @@
+/**************************************************************************//**
+ * @file cmsis_version.h
+ * @brief CMSIS Core(M) Version definitions
+ * @version V5.0.4
+ * @date 23. July 2019
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2019 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined (__clang__)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CMSIS_VERSION_H
+#define __CMSIS_VERSION_H
+
+/* CMSIS Version definitions */
+#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
+#define __CM_CMSIS_VERSION_SUB ( 4U) /*!< [15:0] CMSIS Core(M) sub version */
+#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
+ __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
+#endif
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/core_cm3.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/core_cm3.h
new file mode 100644
index 000000000..74fb87e5c
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/core_cm3.h
@@ -0,0 +1,1943 @@
+/**************************************************************************//**
+ * @file core_cm3.h
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version V5.1.2
+ * @date 04. June 2021
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined (__clang__)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex_M3
+ @{
+ */
+
+#include "cmsis_version.h"
+
+/* CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \
+ __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
+
+#define __CORTEX_M (3U) /*!< Cortex-M Core */
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_FP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TI_ARM__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM3_REV
+ #define __CM3_REV 0x0200U
+ #warning "__CM3_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __VTOR_PRESENT
+ #define __VTOR_PRESENT 1U
+ #warning "__VTOR_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 3U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+#define APSR_Q_Pos 27U /*!< APSR: Q Position */
+#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:1; /*!< bit: 9 Reserved */
+ uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */
+ uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit */
+ uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */
+#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */
+
+#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */
+#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */
+#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24U];
+ __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RESERVED1[24U];
+ __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24U];
+ __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24U];
+ __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56U];
+ __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644U];
+ __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5U];
+ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */
+#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */
+#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */
+
+#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */
+#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */
+
+#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */
+#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */
+
+#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */
+#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */
+
+#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */
+#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */
+
+/* BusFault Status Register (part of SCB Configurable Fault Status Register) */
+#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */
+#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */
+
+#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */
+#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */
+
+#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */
+#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */
+
+#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */
+#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */
+
+#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */
+#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */
+
+#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */
+#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */
+
+/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */
+#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */
+#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */
+
+#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */
+#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */
+
+#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */
+#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */
+
+#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */
+#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */
+
+#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */
+#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */
+
+#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */
+#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+#if defined (__CM3_REV) && (__CM3_REV >= 0x200U)
+ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+#else
+ uint32_t RESERVED1[1U];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#if defined (__CM3_REV) && (__CM3_REV >= 0x200U)
+#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
+#endif
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM)
+ \brief Type definitions for the Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __OM union
+ {
+ __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864U];
+ __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15U];
+ __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15U];
+ __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+ uint32_t RESERVED3[32U];
+ uint32_t RESERVED4[43U];
+ __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */
+ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */
+ uint32_t RESERVED5[6U];
+ __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */
+ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */
+ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */
+ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */
+ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */
+ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */
+ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */
+ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */
+ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */
+ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */
+ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */
+ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
+ \brief Type definitions for the Data Watchpoint and Trace (DWT)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1U];
+ __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1U];
+ __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_TPI Trace Port Interface (TPI)
+ \brief Type definitions for the Trace Port Interface (TPI)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+ __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */
+ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
+ uint32_t RESERVED1[55U];
+ __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
+ uint32_t RESERVED2[131U];
+ __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
+ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
+ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */
+ uint32_t RESERVED3[759U];
+ __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */
+ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */
+ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */
+ uint32_t RESERVED4[1U];
+ __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */
+ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */
+ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */
+ uint32_t RESERVED5[39U];
+ __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */
+ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */
+ uint32_t RESERVED7[8U];
+ __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */
+ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */
+#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */
+
+#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */
+#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */
+#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */
+
+#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */
+#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+#define MPU_TYPE_RALIASES 4U
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Type definitions for the Core Debug Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register. This parameter is interpreted as an uint32_t type.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Core Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
+#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
+#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+#ifdef CMSIS_NVIC_VIRTUAL
+ #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
+ #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
+ #endif
+ #include CMSIS_NVIC_VIRTUAL_HEADER_FILE
+#else
+ #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
+ #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
+ #define NVIC_EnableIRQ __NVIC_EnableIRQ
+ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
+ #define NVIC_DisableIRQ __NVIC_DisableIRQ
+ #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
+ #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
+ #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
+ #define NVIC_GetActive __NVIC_GetActive
+ #define NVIC_SetPriority __NVIC_SetPriority
+ #define NVIC_GetPriority __NVIC_GetPriority
+ #define NVIC_SystemReset __NVIC_SystemReset
+#endif /* CMSIS_NVIC_VIRTUAL */
+
+#ifdef CMSIS_VECTAB_VIRTUAL
+ #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
+ #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
+ #endif
+ #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
+#else
+ #define NVIC_SetVector __NVIC_SetVector
+ #define NVIC_GetVector __NVIC_GetVector
+#endif /* (CMSIS_VECTAB_VIRTUAL) */
+
+#define NVIC_USER_IRQ_OFFSET 16
+
+
+/* The following EXC_RETURN values are saved the LR on exception entry */
+#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
+#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
+#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
+
+
+/**
+ \brief Set Priority Grouping
+ \details Sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Priority grouping field.
+ */
+__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/**
+ \brief Get Priority Grouping
+ \details Reads the priority grouping field from the NVIC Interrupt Controller.
+ \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void)
+{
+ return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+ \brief Enable Interrupt
+ \details Enables a device specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn Device specific interrupt number.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ __COMPILER_BARRIER();
+ NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
+ __COMPILER_BARRIER();
+ }
+}
+
+
+/**
+ \brief Get Interrupt Enable status
+ \details Returns a device specific interrupt enable status from the NVIC interrupt controller.
+ \param [in] IRQn Device specific interrupt number.
+ \return 0 Interrupt is not enabled.
+ \return 1 Interrupt is enabled.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+ }
+ else
+ {
+ return(0U);
+ }
+}
+
+
+/**
+ \brief Disable Interrupt
+ \details Disables a device specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn Device specific interrupt number.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
+ __DSB();
+ __ISB();
+ }
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
+ \param [in] IRQn Device specific interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+ }
+ else
+ {
+ return(0U);
+ }
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of a device specific interrupt in the NVIC pending register.
+ \param [in] IRQn Device specific interrupt number.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
+ }
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of a device specific interrupt in the NVIC pending register.
+ \param [in] IRQn Device specific interrupt number.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
+ }
+}
+
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
+ \param [in] IRQn Device specific interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+ }
+ else
+ {
+ return(0U);
+ }
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of a device specific interrupt or a processor exception.
+ The interrupt number can be positive to specify a device specific interrupt,
+ or negative to specify a processor exception.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ \note The priority cannot be set for every processor exception.
+ */
+__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) >= 0)
+ {
+ NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+ else
+ {
+ SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of a device specific interrupt or a processor exception.
+ The interrupt number can be positive to specify a device specific interrupt,
+ or negative to specify a processor exception.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) >= 0)
+ {
+ return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief Encode Priority
+ \details Encodes the priority for an interrupt with the given priority group,
+ preemptive priority value, and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Used priority group.
+ \param [in] PreemptPriority Preemptive priority value (starting from 0).
+ \param [in] SubPriority Subpriority value (starting from 0).
+ \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ return (
+ ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+ ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
+ );
+}
+
+
+/**
+ \brief Decode Priority
+ \details Decodes an interrupt priority value with a given priority group to
+ preemptive priority value and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+ \param [in] PriorityGroup Used priority group.
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0).
+ \param [out] pSubPriority Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+ *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
+}
+
+
+/**
+ \brief Set Interrupt Vector
+ \details Sets an interrupt vector in SRAM based interrupt vector table.
+ The interrupt number can be positive to specify a device specific interrupt,
+ or negative to specify a processor exception.
+ VTOR must been relocated to SRAM before.
+ \param [in] IRQn Interrupt number
+ \param [in] vector Address of interrupt handler function
+ */
+__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
+{
+ uint32_t *vectors = (uint32_t *)SCB->VTOR;
+ vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
+ /* ARM Application Note 321 states that the M3 does not require the architectural barrier */
+}
+
+
+/**
+ \brief Get Interrupt Vector
+ \details Reads an interrupt vector from interrupt vector table.
+ The interrupt number can be positive to specify a device specific interrupt,
+ or negative to specify a processor exception.
+ \param [in] IRQn Interrupt number.
+ \return Address of interrupt handler function
+ */
+__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
+{
+ uint32_t *vectors = (uint32_t *)SCB->VTOR;
+ return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+
+ for(;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+/* ########################## MPU functions #################################### */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
+
+#include "mpu_armv7.h"
+
+#endif
+
+
+/* ########################## FPU functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_FpuFunctions FPU Functions
+ \brief Function that provides FPU type.
+ @{
+ */
+
+/**
+ \brief get FPU type
+ \details returns the FPU type
+ \returns
+ - \b 0: No FPU
+ - \b 1: Single precision FPU
+ - \b 2: Double + Single precision FPU
+ */
+__STATIC_INLINE uint32_t SCB_GetFPUType(void)
+{
+ return 0U; /* No FPU */
+}
+
+
+/*@} end of CMSIS_Core_FpuFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions ITM Functions
+ \brief Functions that access the ITM debug interface.
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */
+#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+ \brief ITM Send Character
+ \details Transmits a character via the ITM channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+ \param [in] ch Character to transmit.
+ \returns Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
+ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0U].u32 == 0UL)
+ {
+ __NOP();
+ }
+ ITM->PORT[0U].u8 = (uint8_t)ch;
+ }
+ return (ch);
+}
+
+
+/**
+ \brief ITM Receive Character
+ \details Inputs a character via the external variable \ref ITM_RxBuffer.
+ \return Received character.
+ \return -1 No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+ {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/**
+ \brief ITM Check Character
+ \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+ {
+ return (0); /* no character available */
+ }
+ else
+ {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/mpu_armv7.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/mpu_armv7.h
new file mode 100644
index 000000000..d9eedf81a
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/mpu_armv7.h
@@ -0,0 +1,275 @@
+/******************************************************************************
+ * @file mpu_armv7.h
+ * @brief CMSIS MPU API for Armv7-M MPU
+ * @version V5.1.2
+ * @date 25. May 2020
+ ******************************************************************************/
+/*
+ * Copyright (c) 2017-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined (__clang__)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef ARM_MPU_ARMV7_H
+#define ARM_MPU_ARMV7_H
+
+#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
+#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
+#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
+#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
+#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
+#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
+#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
+#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
+#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
+#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
+#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
+#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
+#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
+#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
+#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
+#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
+#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
+#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
+#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
+#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
+#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
+#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
+#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
+#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
+#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
+#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
+#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
+#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
+
+#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
+#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
+#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only
+#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
+#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only
+#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access
+
+/** MPU Region Base Address Register Value
+*
+* \param Region The region to be configured, number 0 to 15.
+* \param BaseAddress The base address for the region.
+*/
+#define ARM_MPU_RBAR(Region, BaseAddress) \
+ (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
+ ((Region) & MPU_RBAR_REGION_Msk) | \
+ (MPU_RBAR_VALID_Msk))
+
+/**
+* MPU Memory Access Attributes
+*
+* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
+* \param IsShareable Region is shareable between multiple bus masters.
+* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
+* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
+*/
+#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
+ ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
+ (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
+ (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
+ (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
+
+/**
+* MPU Region Attribute and Size Register Value
+*
+* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
+* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
+* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
+* \param SubRegionDisable Sub-region disable field.
+* \param Size Region size of the region to be configured, for example 4K, 8K.
+*/
+#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
+ ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
+ (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
+ (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \
+ (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
+ (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
+ (((MPU_RASR_ENABLE_Msk))))
+
+/**
+* MPU Region Attribute and Size Register Value
+*
+* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
+* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
+* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
+* \param IsShareable Region is shareable between multiple bus masters.
+* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
+* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
+* \param SubRegionDisable Sub-region disable field.
+* \param Size Region size of the region to be configured, for example 4K, 8K.
+*/
+#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
+ ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
+
+/**
+* MPU Memory Access Attribute for strongly ordered memory.
+* - TEX: 000b
+* - Shareable
+* - Non-cacheable
+* - Non-bufferable
+*/
+#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
+
+/**
+* MPU Memory Access Attribute for device memory.
+* - TEX: 000b (if shareable) or 010b (if non-shareable)
+* - Shareable or non-shareable
+* - Non-cacheable
+* - Bufferable (if shareable) or non-bufferable (if non-shareable)
+*
+* \param IsShareable Configures the device memory as shareable or non-shareable.
+*/
+#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
+
+/**
+* MPU Memory Access Attribute for normal memory.
+* - TEX: 1BBb (reflecting outer cacheability rules)
+* - Shareable or non-shareable
+* - Cacheable or non-cacheable (reflecting inner cacheability rules)
+* - Bufferable or non-bufferable (reflecting inner cacheability rules)
+*
+* \param OuterCp Configures the outer cache policy.
+* \param InnerCp Configures the inner cache policy.
+* \param IsShareable Configures the memory as shareable or non-shareable.
+*/
+#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U))
+
+/**
+* MPU Memory Access Attribute non-cacheable policy.
+*/
+#define ARM_MPU_CACHEP_NOCACHE 0U
+
+/**
+* MPU Memory Access Attribute write-back, write and read allocate policy.
+*/
+#define ARM_MPU_CACHEP_WB_WRA 1U
+
+/**
+* MPU Memory Access Attribute write-through, no write allocate policy.
+*/
+#define ARM_MPU_CACHEP_WT_NWA 2U
+
+/**
+* MPU Memory Access Attribute write-back, no write allocate policy.
+*/
+#define ARM_MPU_CACHEP_WB_NWA 3U
+
+
+/**
+* Struct for a single MPU Region
+*/
+typedef struct {
+ uint32_t RBAR; //!< The region base address register value (RBAR)
+ uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
+} ARM_MPU_Region_t;
+
+/** Enable the MPU.
+* \param MPU_Control Default access permissions for unconfigured regions.
+*/
+__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
+{
+ __DMB();
+ MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
+#ifdef SCB_SHCSR_MEMFAULTENA_Msk
+ SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
+#endif
+ __DSB();
+ __ISB();
+}
+
+/** Disable the MPU.
+*/
+__STATIC_INLINE void ARM_MPU_Disable(void)
+{
+ __DMB();
+#ifdef SCB_SHCSR_MEMFAULTENA_Msk
+ SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
+#endif
+ MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
+ __DSB();
+ __ISB();
+}
+
+/** Clear and disable the given MPU region.
+* \param rnr Region number to be cleared.
+*/
+__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
+{
+ MPU->RNR = rnr;
+ MPU->RASR = 0U;
+}
+
+/** Configure an MPU region.
+* \param rbar Value for RBAR register.
+* \param rasr Value for RASR register.
+*/
+__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
+{
+ MPU->RBAR = rbar;
+ MPU->RASR = rasr;
+}
+
+/** Configure the given MPU region.
+* \param rnr Region number to be configured.
+* \param rbar Value for RBAR register.
+* \param rasr Value for RASR register.
+*/
+__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
+{
+ MPU->RNR = rnr;
+ MPU->RBAR = rbar;
+ MPU->RASR = rasr;
+}
+
+/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load().
+* \param dst Destination data is copied to.
+* \param src Source data is copied from.
+* \param len Amount of data words to be copied.
+*/
+__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
+{
+ uint32_t i;
+ for (i = 0U; i < len; ++i)
+ {
+ dst[i] = src[i];
+ }
+}
+
+/** Load the given number of MPU regions from a table.
+* \param table Pointer to the MPU configuration table.
+* \param cnt Amount of regions to be configured.
+*/
+__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
+{
+ const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
+ while (cnt > MPU_TYPE_RALIASES) {
+ ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
+ table += MPU_TYPE_RALIASES;
+ cnt -= MPU_TYPE_RALIASES;
+ }
+ ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
+}
+
+#endif
diff --git a/tests/projects/embed/mdk/hello/src/lib/cmsis/system_ARMCM3.h b/tests/projects/embed/mdk/hello/src/lib/cmsis/system_ARMCM3.h
new file mode 100644
index 000000000..5d1237770
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/lib/cmsis/system_ARMCM3.h
@@ -0,0 +1,62 @@
+/**************************************************************************//**
+ * @file system_ARMCM3.h
+ * @brief CMSIS Device System Header File for
+ * ARMCM3 Device
+ * @version V5.3.2
+ * @date 15. November 2019
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SYSTEM_ARMCM3_H
+#define SYSTEM_ARMCM3_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ \brief Exception / Interrupt Handler Function Prototype
+*/
+typedef void(*VECTOR_TABLE_Type)(void);
+
+/**
+ \brief System Clock Frequency (Core Clock)
+*/
+extern uint32_t SystemCoreClock;
+
+/**
+ \brief Setup the microcontroller system.
+
+ Initialize the System and update the SystemCoreClock variable.
+ */
+extern void SystemInit (void);
+
+
+/**
+ \brief Update SystemCoreClock variable.
+
+ Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
+ */
+extern void SystemCoreClockUpdate (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_ARMCM3_H */
diff --git a/tests/projects/embed/mdk/hello/src/main.c b/tests/projects/embed/mdk/hello/src/main.c
new file mode 100644
index 000000000..28d909a18
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/main.c
@@ -0,0 +1,6 @@
+int foo(int x);
+
+int main()
+{
+ return foo(1);
+}
diff --git a/tests/projects/embed/mdk/hello/src/startup_ARMCM3.s b/tests/projects/embed/mdk/hello/src/startup_ARMCM3.s
new file mode 100644
index 000000000..efe40c1e3
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/startup_ARMCM3.s
@@ -0,0 +1,172 @@
+;/**************************************************************************//**
+; * @file startup_ARMCM3.s
+; * @brief CMSIS Core Device Startup File for
+; * ARMCM3 Device
+; * @version V1.0.1
+; * @date 23. July 2019
+; ******************************************************************************/
+;/*
+; * Copyright (c) 2009-2019 Arm Limited. All rights reserved.
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Licensed under the Apache License, Version 2.0 (the License); you may
+; * not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; * www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; */
+
+;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+
+
+;<h> Stack Configuration
+; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;</h>
+
+Stack_Size EQU 0x00000400
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+__stack_limit
+Stack_Mem SPACE Stack_Size
+__initial_sp
+
+
+;<h> Heap Configuration
+; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;</h>
+
+Heap_Size EQU 0x00000C00
+
+ IF Heap_Size != 0 ; Heap is provided
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+ ENDIF
+
+
+ PRESERVE8
+ THUMB
+
+
+; Vector Table Mapped to Address 0 at Reset
+
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+ EXPORT __Vectors_End
+ EXPORT __Vectors_Size
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler ; Reset Handler
+ DCD NMI_Handler ; -14 NMI Handler
+ DCD HardFault_Handler ; -13 Hard Fault Handler
+ DCD MemManage_Handler ; -12 MPU Fault Handler
+ DCD BusFault_Handler ; -11 Bus Fault Handler
+ DCD UsageFault_Handler ; -10 Usage Fault Handler
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVC_Handler ; -5 SVCall Handler
+ DCD DebugMon_Handler ; -4 Debug Monitor Handler
+ DCD 0 ; Reserved
+ DCD PendSV_Handler ; -2 PendSV Handler
+ DCD SysTick_Handler ; -1 SysTick Handler
+
+ ; Interrupts
+ DCD Interrupt0_Handler ; 0 Interrupt 0
+ DCD Interrupt1_Handler ; 1 Interrupt 1
+ DCD Interrupt2_Handler ; 2 Interrupt 2
+ DCD Interrupt3_Handler ; 3 Interrupt 3
+ DCD Interrupt4_Handler ; 4 Interrupt 4
+ DCD Interrupt5_Handler ; 5 Interrupt 5
+ DCD Interrupt6_Handler ; 6 Interrupt 6
+ DCD Interrupt7_Handler ; 7 Interrupt 7
+ DCD Interrupt8_Handler ; 8 Interrupt 8
+ DCD Interrupt9_Handler ; 9 Interrupt 9
+
+ SPACE (214 * 4) ; Interrupts 10 .. 224 are left out
+__Vectors_End
+__Vectors_Size EQU __Vectors_End - __Vectors
+
+
+ AREA |.text|, CODE, READONLY
+
+; Reset Handler
+
+Reset_Handler PROC
+ EXPORT Reset_Handler [WEAK]
+ IMPORT SystemInit
+ IMPORT __main
+
+ LDR R0, =SystemInit
+ BLX R0
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+; The default macro is not used for HardFault_Handler
+; because this results in a poor debug illusion.
+HardFault_Handler PROC
+ EXPORT HardFault_Handler [WEAK]
+ B .
+ ENDP
+
+; Macro to define default exception/interrupt handlers.
+; Default handler are weak symbols with an endless loop.
+; They can be overwritten by real handlers.
+ MACRO
+ Set_Default_Handler $Handler_Name
+$Handler_Name PROC
+ EXPORT $Handler_Name [WEAK]
+ B .
+ ENDP
+ MEND
+
+
+; Default exception/interrupt handler
+
+ Set_Default_Handler NMI_Handler
+ Set_Default_Handler MemManage_Handler
+ Set_Default_Handler BusFault_Handler
+ Set_Default_Handler UsageFault_Handler
+ Set_Default_Handler SVC_Handler
+ Set_Default_Handler DebugMon_Handler
+ Set_Default_Handler PendSV_Handler
+ Set_Default_Handler SysTick_Handler
+
+ Set_Default_Handler Interrupt0_Handler
+ Set_Default_Handler Interrupt1_Handler
+ Set_Default_Handler Interrupt2_Handler
+ Set_Default_Handler Interrupt3_Handler
+ Set_Default_Handler Interrupt4_Handler
+ Set_Default_Handler Interrupt5_Handler
+ Set_Default_Handler Interrupt6_Handler
+ Set_Default_Handler Interrupt7_Handler
+ Set_Default_Handler Interrupt8_Handler
+ Set_Default_Handler Interrupt9_Handler
+
+ ALIGN
+
+
+; User setup Stack & Heap
+
+ IF :LNOT::DEF:__MICROLIB
+ IMPORT __use_two_region_memory
+ ENDIF
+
+ EXPORT __stack_limit
+ EXPORT __initial_sp
+ IF Heap_Size != 0 ; Heap is provided
+ EXPORT __heap_base
+ EXPORT __heap_limit
+ ENDIF
+
+ END
diff --git a/tests/projects/embed/mdk/hello/src/system_ARMCM3.c b/tests/projects/embed/mdk/hello/src/system_ARMCM3.c
new file mode 100644
index 000000000..19484537f
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/src/system_ARMCM3.c
@@ -0,0 +1,65 @@
+/**************************************************************************//**
+ * @file system_ARMCM3.c
+ * @brief CMSIS Device System Source File for
+ * ARMCM3 Device
+ * @version V1.0.1
+ * @date 15. November 2019
+ ******************************************************************************/
+/*
+ * Copyright (c) 2009-2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ARMCM3.h"
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+#define XTAL (50000000UL) /* Oscillator frequency */
+
+#define SYSTEM_CLOCK (XTAL / 2U)
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+extern const VECTOR_TABLE_Type __VECTOR_TABLE[240];
+
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Core Clock Frequency */
+
+
+/*----------------------------------------------------------------------------
+ System Core Clock update function
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)
+{
+ SystemCoreClock = SYSTEM_CLOCK;
+}
+
+/*----------------------------------------------------------------------------
+ System initialization function
+ *----------------------------------------------------------------------------*/
+void SystemInit (void)
+{
+
+#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
+ SCB->VTOR = (uint32_t) &(__VECTOR_TABLE[0]);
+#endif
+
+ SystemCoreClock = SYSTEM_CLOCK;
+}
diff --git a/tests/projects/embed/mdk/hello/xmake.lua b/tests/projects/embed/mdk/hello/xmake.lua
new file mode 100644
index 000000000..6afb714af
--- /dev/null
+++ b/tests/projects/embed/mdk/hello/xmake.lua
@@ -0,0 +1,13 @@
+add_rules("mode.debug", "mode.release")
+
+set_runtimes("microlib")
+
+target("foo")
+ add_rules("mdk.static")
+ add_files("src/foo/*.c")
+
+target("hello")
+ add_deps("foo")
+ add_rules("mdk.console")
+ add_files("src/*.c", "src/*.s")
+ add_includedirs("src/lib/cmsis")
diff --git a/tests/projects/bpf/minimal/src/minimal.bpf.c b/tests/projects/linux/bpf/minimal/src/minimal.bpf.c
index ea1eeefbb..ea1eeefbb 100644
--- a/tests/projects/bpf/minimal/src/minimal.bpf.c
+++ b/tests/projects/linux/bpf/minimal/src/minimal.bpf.c
diff --git a/tests/projects/bpf/minimal/src/minimal.c b/tests/projects/linux/bpf/minimal/src/minimal.c
index 4b6ec3181..4b6ec3181 100644
--- a/tests/projects/bpf/minimal/src/minimal.c
+++ b/tests/projects/linux/bpf/minimal/src/minimal.c
diff --git a/tests/projects/bpf/minimal/test.lua b/tests/projects/linux/bpf/minimal/test.lua
index 2856a3831..2856a3831 100644
--- a/tests/projects/bpf/minimal/test.lua
+++ b/tests/projects/linux/bpf/minimal/test.lua
diff --git a/tests/projects/bpf/minimal/xmake.lua b/tests/projects/linux/bpf/minimal/xmake.lua
index 8507b8aa1..8507b8aa1 100644
--- a/tests/projects/bpf/minimal/xmake.lua
+++ b/tests/projects/linux/bpf/minimal/xmake.lua
diff --git a/tests/projects/linux/driver/hello/src/add.c b/tests/projects/linux/driver/hello/src/add.c
new file mode 100644
index 000000000..59aab4983
--- /dev/null
+++ b/tests/projects/linux/driver/hello/src/add.c
@@ -0,0 +1,3 @@
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/projects/linux/driver/hello/src/hello.c b/tests/projects/linux/driver/hello/src/hello.c
new file mode 100644
index 000000000..414a03bb2
--- /dev/null
+++ b/tests/projects/linux/driver/hello/src/hello.c
@@ -0,0 +1,23 @@
+#include <linux/init.h>
+#include <linux/module.h>
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Ruki");
+MODULE_DESCRIPTION("A simple Hello World Module");
+MODULE_ALIAS("a simplest module");
+
+int add(int a, int b);
+
+int hello_init(void)
+{
+ printk(KERN_INFO "Hello World: %d\n", add(1, 2));
+ return 0;
+}
+
+void hello_exit(void)
+{
+ printk(KERN_INFO "Goodbye World\n");
+}
+
+module_init(hello_init);
+module_exit(hello_exit);
diff --git a/tests/projects/linux/driver/hello/xmake.lua b/tests/projects/linux/driver/hello/xmake.lua
new file mode 100644
index 000000000..bac728434
--- /dev/null
+++ b/tests/projects/linux/driver/hello/xmake.lua
@@ -0,0 +1,7 @@
+add_requires("linux-headers", {configs = {driver_modules = true}})
+
+target("hello")
+ add_rules("platform.linux.driver")
+ add_files("src/*.c")
+ add_packages("linux-headers")
+ set_license("GPL-2.0")
diff --git a/tests/projects/linux/driver/hello_custom/src/add.c b/tests/projects/linux/driver/hello_custom/src/add.c
new file mode 100644
index 000000000..59aab4983
--- /dev/null
+++ b/tests/projects/linux/driver/hello_custom/src/add.c
@@ -0,0 +1,3 @@
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/projects/linux/driver/hello_custom/src/hello.c b/tests/projects/linux/driver/hello_custom/src/hello.c
new file mode 100644
index 000000000..414a03bb2
--- /dev/null
+++ b/tests/projects/linux/driver/hello_custom/src/hello.c
@@ -0,0 +1,23 @@
+#include <linux/init.h>
+#include <linux/module.h>
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Ruki");
+MODULE_DESCRIPTION("A simple Hello World Module");
+MODULE_ALIAS("a simplest module");
+
+int add(int a, int b);
+
+int hello_init(void)
+{
+ printk(KERN_INFO "Hello World: %d\n", add(1, 2));
+ return 0;
+}
+
+void hello_exit(void)
+{
+ printk(KERN_INFO "Goodbye World\n");
+}
+
+module_init(hello_init);
+module_exit(hello_exit);
diff --git a/tests/projects/linux/driver/hello_custom/xmake.lua b/tests/projects/linux/driver/hello_custom/xmake.lua
new file mode 100644
index 000000000..846bddc55
--- /dev/null
+++ b/tests/projects/linux/driver/hello_custom/xmake.lua
@@ -0,0 +1,6 @@
+option("linux-headers", {showmenu = true, description = "Set linux-headers path."})
+target("hello")
+ add_rules("platform.linux.driver")
+ add_files("src/*.c")
+ set_values("linux.driver.linux-headers", "$(linux-headers)")
+
diff --git a/tests/projects/linux/driver/hello_makefile/Makefile b/tests/projects/linux/driver/hello_makefile/Makefile
new file mode 100644
index 000000000..1d5aa92b4
--- /dev/null
+++ b/tests/projects/linux/driver/hello_makefile/Makefile
@@ -0,0 +1,15 @@
+ifneq ($(KERNELRELEASE),)
+ obj-m := hello.o
+ hello-objs := ./src/hello.o ./src/add.o
+else
+ KERN_DIR ?= /usr/src/linux-headers-5.11.0-41-generic/
+ PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KERN_DIR) V=1 M=$(PWD) modules
+endif
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
+ rm -rf src/*.o src/*~ core src/.depend src/.*.cmd src/*.ko src/*.mod.c src/.tmp_versions
+
diff --git a/tests/projects/linux/driver/hello_makefile/src/add.c b/tests/projects/linux/driver/hello_makefile/src/add.c
new file mode 100644
index 000000000..59aab4983
--- /dev/null
+++ b/tests/projects/linux/driver/hello_makefile/src/add.c
@@ -0,0 +1,3 @@
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/projects/linux/driver/hello_makefile/src/hello.c b/tests/projects/linux/driver/hello_makefile/src/hello.c
new file mode 100644
index 000000000..414a03bb2
--- /dev/null
+++ b/tests/projects/linux/driver/hello_makefile/src/hello.c
@@ -0,0 +1,23 @@
+#include <linux/init.h>
+#include <linux/module.h>
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Ruki");
+MODULE_DESCRIPTION("A simple Hello World Module");
+MODULE_ALIAS("a simplest module");
+
+int add(int a, int b);
+
+int hello_init(void)
+{
+ printk(KERN_INFO "Hello World: %d\n", add(1, 2));
+ return 0;
+}
+
+void hello_exit(void)
+{
+ printk(KERN_INFO "Goodbye World\n");
+}
+
+module_init(hello_init);
+module_exit(hello_exit);
diff --git a/tests/projects/nim/console/src/main b/tests/projects/nim/console/src/main
new file mode 100755
index 000000000..84f0819ac
--- /dev/null
+++ b/tests/projects/nim/console/src/main
Binary files differ
diff --git a/tests/projects/nim/console/src/main.nim b/tests/projects/nim/console/src/main.nim
new file mode 100644
index 000000000..17179284f
--- /dev/null
+++ b/tests/projects/nim/console/src/main.nim
@@ -0,0 +1 @@
+echo "hello xmake!"
diff --git a/tests/projects/nim/console/xmake.lua b/tests/projects/nim/console/xmake.lua
new file mode 100644
index 000000000..40459a274
--- /dev/null
+++ b/tests/projects/nim/console/xmake.lua
@@ -0,0 +1,5 @@
+add_rules("mode.debug", "mode.release")
+
+target("test")
+ set_kind("binary")
+ add_files("src/main.nim")
diff --git a/tests/projects/nim/console_with_c/src/foo.c b/tests/projects/nim/console_with_c/src/foo.c
new file mode 100644
index 000000000..7e3f727d6
--- /dev/null
+++ b/tests/projects/nim/console_with_c/src/foo.c
@@ -0,0 +1,3 @@
+int foo(int n) {
+ return n;
+}
diff --git a/tests/projects/nim/console_with_c/src/main.nim b/tests/projects/nim/console_with_c/src/main.nim
new file mode 100644
index 000000000..1be3abe69
--- /dev/null
+++ b/tests/projects/nim/console_with_c/src/main.nim
@@ -0,0 +1,3 @@
+proc foo(n: int): int {.cdecl, importc}
+
+echo foo(2)
diff --git a/tests/projects/nim/console_with_c/xmake.lua b/tests/projects/nim/console_with_c/xmake.lua
new file mode 100644
index 000000000..c2d067cd6
--- /dev/null
+++ b/tests/projects/nim/console_with_c/xmake.lua
@@ -0,0 +1,10 @@
+add_rules("mode.debug", "mode.release")
+
+target("foo")
+ set_kind("static")
+ add_files("src/*.c")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.nim")
diff --git a/tests/projects/nim/native_package/src/main.nim b/tests/projects/nim/native_package/src/main.nim
new file mode 100644
index 000000000..a3368303a
--- /dev/null
+++ b/tests/projects/nim/native_package/src/main.nim
@@ -0,0 +1,3 @@
+proc zlibVersion(): cstring {.cdecl, importc}
+
+echo zlibVersion()
diff --git a/tests/projects/nim/native_package/xmake.lua b/tests/projects/nim/native_package/xmake.lua
new file mode 100644
index 000000000..924ee9632
--- /dev/null
+++ b/tests/projects/nim/native_package/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("zlib")
+
+target("test")
+ set_kind("binary")
+ add_files("src/main.nim")
+ add_packages("zlib")
diff --git a/tests/projects/nim/nimble_package/src/main.nim b/tests/projects/nim/nimble_package/src/main.nim
new file mode 100644
index 000000000..b78aa2495
--- /dev/null
+++ b/tests/projects/nim/nimble_package/src/main.nim
@@ -0,0 +1,3 @@
+import zip/zlib
+
+echo zlibVersion()
diff --git a/tests/projects/nim/nimble_package/xmake.lua b/tests/projects/nim/nimble_package/xmake.lua
new file mode 100644
index 000000000..45e6f3132
--- /dev/null
+++ b/tests/projects/nim/nimble_package/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("nimble::zip >0.3")
+
+target("test")
+ set_kind("binary")
+ add_files("src/main.nim")
+ add_packages("nimble::zip")
diff --git a/tests/projects/nim/shared_library/src/foo.nim b/tests/projects/nim/shared_library/src/foo.nim
new file mode 100644
index 000000000..db968d723
--- /dev/null
+++ b/tests/projects/nim/shared_library/src/foo.nim
@@ -0,0 +1,5 @@
+proc foo(n: int): int {.cdecl, exportc, dynlib.} =
+ if n < 2:
+ result = n
+ else:
+ result = foo(n - 1) + (n - 2).foo
diff --git a/tests/projects/nim/shared_library/src/main.nim b/tests/projects/nim/shared_library/src/main.nim
new file mode 100644
index 000000000..81a64bda0
--- /dev/null
+++ b/tests/projects/nim/shared_library/src/main.nim
@@ -0,0 +1,4 @@
+proc foo(n: int): int {.cdecl, importc}
+
+echo foo(2)
+
diff --git a/tests/projects/nim/shared_library/xmake.lua b/tests/projects/nim/shared_library/xmake.lua
new file mode 100644
index 000000000..b560961d6
--- /dev/null
+++ b/tests/projects/nim/shared_library/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+
+target("foo")
+ set_kind("shared")
+ add_files("src/foo.nim")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.nim")
+
+
diff --git a/tests/projects/nim/static_library/src/foo.nim b/tests/projects/nim/static_library/src/foo.nim
new file mode 100644
index 000000000..be0904262
--- /dev/null
+++ b/tests/projects/nim/static_library/src/foo.nim
@@ -0,0 +1,6 @@
+proc foo(n: int): int {.cdecl, exportc} =
+ if n < 2:
+ result = n
+ else:
+ result = foo(n - 1) + (n - 2).foo
+
diff --git a/tests/projects/nim/static_library/src/main.nim b/tests/projects/nim/static_library/src/main.nim
new file mode 100644
index 000000000..1be3abe69
--- /dev/null
+++ b/tests/projects/nim/static_library/src/main.nim
@@ -0,0 +1,3 @@
+proc foo(n: int): int {.cdecl, importc}
+
+echo foo(2)
diff --git a/tests/projects/nim/static_library/xmake.lua b/tests/projects/nim/static_library/xmake.lua
new file mode 100644
index 000000000..7ef38314a
--- /dev/null
+++ b/tests/projects/nim/static_library/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+
+target("foo")
+ set_kind("static")
+ add_files("src/foo.nim")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.nim")
+
+
diff --git a/tests/projects/objc/metal_app/.gitignore b/tests/projects/objc/metal_app/.gitignore
new file mode 100644
index 000000000..9e50718e2
--- /dev/null
+++ b/tests/projects/objc/metal_app/.gitignore
@@ -0,0 +1,21 @@
+# See LICENSE folder for this sample’s licensing information.
+#
+# Apple sample code gitignore configuration.
+
+# Finder
+.DS_Store
+
+# Xcode - User files
+xcuserdata/
+
+**/*.xcodeproj/project.xcworkspace/*
+!**/*.xcodeproj/project.xcworkspace/xcshareddata
+
+**/*.xcodeproj/project.xcworkspace/xcshareddata/*
+!**/*.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
+
+**/*.playground/playground.xcworkspace/*
+!**/*.playground/playground.xcworkspace/xcshareddata
+
+**/*.playground/playground.xcworkspace/xcshareddata/*
+!**/*.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
diff --git a/tests/projects/objc/metal_app/Application/AAPLAppDelegate.h b/tests/projects/objc/metal_app/Application/AAPLAppDelegate.h
new file mode 100644
index 000000000..a4e4a7fef
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/AAPLAppDelegate.h
@@ -0,0 +1,14 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Header for our iOS & tvOS application delegate
+*/
+
+#import <UIKit/UIKit.h>
+
+@interface AAPLAppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end
diff --git a/tests/projects/objc/metal_app/Application/AAPLAppDelegate.m b/tests/projects/objc/metal_app/Application/AAPLAppDelegate.m
new file mode 100644
index 000000000..58b31e876
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/AAPLAppDelegate.m
@@ -0,0 +1,16 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Implementation of our iOS & tvOS application delegate
+*/
+
+#import "AAPLAppDelegate.h"
+
+@implementation AAPLAppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ return YES;
+}
+
+@end
diff --git a/tests/projects/objc/metal_app/Application/AAPLViewController.h b/tests/projects/objc/metal_app/Application/AAPLViewController.h
new file mode 100644
index 000000000..f9ecea64f
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/AAPLViewController.h
@@ -0,0 +1,23 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Header for our our cross-platform view controller
+*/
+
+#if defined(TARGET_IOS) || defined(TARGET_TVOS)
+@import UIKit;
+#define PlatformViewController UIViewController
+#else
+@import AppKit;
+#define PlatformViewController NSViewController
+#endif
+
+@import MetalKit;
+
+#import "AAPLRenderer.h"
+
+// Our view controller
+@interface AAPLViewController : PlatformViewController
+
+@end
diff --git a/tests/projects/objc/metal_app/Application/AAPLViewController.m b/tests/projects/objc/metal_app/Application/AAPLViewController.m
new file mode 100644
index 000000000..dc02a8c4a
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/AAPLViewController.m
@@ -0,0 +1,39 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Implementation of our cross-platform view controller
+*/
+
+#import "AAPLViewController.h"
+#import "AAPLRenderer.h"
+
+@implementation AAPLViewController
+{
+ MTKView *_view;
+
+ AAPLRenderer *_renderer;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ // Set the view to use the default device
+ _view = (MTKView *)self.view;
+
+ _view.device = MTLCreateSystemDefaultDevice();
+
+ NSAssert(_view.device, @"Metal is not supported on this device");
+
+ _renderer = [[AAPLRenderer alloc] initWithMetalKitView:_view];
+
+ NSAssert(_renderer, @"Renderer failed initialization");
+
+ // Initialize our renderer with the view size
+ [_renderer mtkView:_view drawableSizeWillChange:_view.drawableSize];
+
+ _view.delegate = _renderer;
+}
+
+@end
diff --git a/tests/projects/objc/metal_app/Application/iOS/Base.lproj/LaunchScreen.storyboard b/tests/projects/objc/metal_app/Application/iOS/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 000000000..fdf3f97d1
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/iOS/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+ <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/tests/projects/objc/metal_app/Application/iOS/Base.lproj/Main.storyboard b/tests/projects/objc/metal_app/Application/iOS/Base.lproj/Main.storyboard
new file mode 100644
index 000000000..037265c96
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/iOS/Base.lproj/Main.storyboard
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16E138" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BV1-FR-VrT">
+ <device id="retina4_7" orientation="portrait">
+ <adaptation id="fullscreen"/>
+ </device>
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tXr-a1-R10">
+ <objects>
+ <viewController id="BV1-FR-VrT" customClass="AAPLViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="8aa-yV-Osq"/>
+ <viewControllerLayoutGuide type="bottom" id="qHh-Mt-9TT"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="3se-qz-xqx" customClass="MTKView">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="SZV-WD-TEh" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/tests/projects/objc/metal_app/Application/iOS/Info.plist b/tests/projects/objc/metal_app/Application/iOS/Info.plist
new file mode 100644
index 000000000..154374326
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/iOS/Info.plist
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UIStatusBarHidden</key>
+ <true/>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/tests/projects/objc/metal_app/Application/macOS/Base.lproj/Main.storyboard b/tests/projects/objc/metal_app/Application/macOS/Base.lproj/Main.storyboard
new file mode 100644
index 000000000..e6be158ce
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/macOS/Base.lproj/Main.storyboard
@@ -0,0 +1,693 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14724.1" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14724.1"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--Application-->
+ <scene sceneID="JPo-4y-FX3">
+ <objects>
+ <application id="hnw-xV-0zn" sceneMemberID="viewController">
+ <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+ <items>
+ <menuItem title="Hello Triangle" id="1Xt-HY-uBw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Hello Triangle" systemMenu="apple" id="uQy-DD-JDr">
+ <items>
+ <menuItem title="About Hello Triangle" id="5kV-Vb-QxS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+ <menuItem title="Services" id="NMo-om-nkz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+ <menuItem title="Hide Hello Triangle" keyEquivalent="h" id="Olw-nP-bQN">
+ <connections>
+ <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Show All" id="Kd2-mp-pUS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+ <menuItem title="Quit Hello Triangle" keyEquivalent="q" id="4sb-4s-VLi">
+ <connections>
+ <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="File" id="dMs-cI-mzQ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="File" id="bib-Uj-vzu">
+ <items>
+ <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
+ <connections>
+ <action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
+ <connections>
+ <action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open Recent" id="tXI-mr-wws">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
+ <items>
+ <menuItem title="Clear Menu" id="vNY-rz-j42">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
+ <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
+ <connections>
+ <action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
+ <connections>
+ <action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
+ <connections>
+ <action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
+ <connections>
+ <action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
+ <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
+ <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
+ <connections>
+ <action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
+ <connections>
+ <action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Edit" id="5QF-Oa-p0T">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+ <items>
+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+ <connections>
+ <action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+ <connections>
+ <action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+ <connections>
+ <action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+ <connections>
+ <action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+ <connections>
+ <action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Delete" id="pa3-QI-u2k">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+ <connections>
+ <action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+ <menuItem title="Find" id="4EN-yA-p0u">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Find" id="1b7-l0-nxx">
+ <items>
+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+ <connections>
+ <action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+ <items>
+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+ <connections>
+ <action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+ <connections>
+ <action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Substitutions" id="9ic-FL-obx">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+ <items>
+ <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Links" id="cwL-P1-jid">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Data Detectors" id="tRr-pd-1PS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Transformations" id="2oI-Rn-ZJC">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+ <items>
+ <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Speech" id="xrE-MZ-jX0">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+ <items>
+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Format" id="jxT-CU-nIS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Format" id="GEO-Iw-cKr">
+ <items>
+ <menuItem title="Font" id="Gi5-1S-RQB">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
+ <items>
+ <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq"/>
+ <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27"/>
+ <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq"/>
+ <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
+ <connections>
+ <action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
+ <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL"/>
+ <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST"/>
+ <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
+ <menuItem title="Kern" id="jBQ-r6-VK2">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
+ <items>
+ <menuItem title="Use Default" id="GUa-eO-cwY">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="cDB-IK-hbR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Tighten" id="46P-cB-AYj">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Loosen" id="ogc-rX-tC1">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Ligatures" id="o6e-r0-MWq">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
+ <items>
+ <menuItem title="Use Default" id="agt-UL-0e3">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="J7y-lM-qPV">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use All" id="xQD-1f-W4t">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Baseline" id="OaQ-X3-Vso">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Baseline" id="ijk-EB-dga">
+ <items>
+ <menuItem title="Use Default" id="3Om-Ey-2VK">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Superscript" id="Rqc-34-cIF">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Subscript" id="I0S-gh-46l">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Raise" id="2h7-ER-AoG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Lower" id="1tx-W0-xDw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
+ <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
+ <connections>
+ <action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
+ <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Text" id="Fal-I4-PZk">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Text" id="d9c-me-L2H">
+ <items>
+ <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
+ <connections>
+ <action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
+ <connections>
+ <action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Justify" id="J5U-5w-g23">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
+ <connections>
+ <action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
+ <menuItem title="Writing Direction" id="H1b-Si-o9J">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
+ <items>
+ <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="YGs-j5-SAR">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
+ </connections>
+ </menuItem>
+ <menuItem id="Lbh-J2-qVU">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
+ </connections>
+ </menuItem>
+ <menuItem id="jFq-tB-4Kx">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
+ <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="Nop-cj-93Q">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
+ </connections>
+ </menuItem>
+ <menuItem id="BgM-ve-c93">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
+ </connections>
+ </menuItem>
+ <menuItem id="RB4-Sm-HuC">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
+ <menuItem title="Show Ruler" id="vLm-3I-IUL">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="View" id="H8h-7b-M4v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="View" id="HyV-fh-RgO">
+ <items>
+ <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
+ <menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Window" id="aUF-d1-5bR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+ <items>
+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+ <connections>
+ <action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Zoom" id="R4o-n2-Eq4">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Help" id="wpr-3q-Mcd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
+ <items>
+ <menuItem title="Hello Triangle Help" keyEquivalent="?" id="FKE-Sm-Kum">
+ <connections>
+ <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </application>
+ <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="75" y="0.0"/>
+ </scene>
+ <!--Window Controller-->
+ <scene sceneID="R2V-B0-nI4">
+ <objects>
+ <windowController id="B8D-0N-5wS" sceneMemberID="viewController">
+ <window key="window" title="Hello Triangle" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="IQv-IB-iLA">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="196" y="240" width="480" height="270"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
+ <connections>
+ <outlet property="delegate" destination="B8D-0N-5wS" id="c2Y-5V-HmV"/>
+ </connections>
+ </window>
+ <connections>
+ <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
+ </connections>
+ </windowController>
+ <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="75" y="250"/>
+ </scene>
+ <!--View Controller-->
+ <scene sceneID="hIz-AP-VOD">
+ <objects>
+ <viewController id="XfG-lQ-9wD" customClass="AAPLViewController" sceneMemberID="viewController">
+ <view key="view" wantsLayer="YES" id="m2S-Jp-Qdl" customClass="MTKView">
+ <rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </view>
+ </viewController>
+ <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="75" y="817"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/tests/projects/objc/metal_app/Application/macOS/Info.plist b/tests/projects/objc/metal_app/Application/macOS/Info.plist
new file mode 100644
index 000000000..f16cc0681
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/macOS/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
+ <key>NSMainStoryboardFile</key>
+ <string>Main</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/tests/projects/objc/metal_app/Application/main.m b/tests/projects/objc/metal_app/Application/main.m
new file mode 100644
index 000000000..b35c0d5ec
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/main.m
@@ -0,0 +1,36 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Application entry point for all platforms
+*/
+
+#if defined(TARGET_IOS) || defined(TARGET_TVOS)
+#import <UIKit/UIKit.h>
+#import <TargetConditionals.h>
+#import <Availability.h>
+#import "AAPLAppDelegate.h"
+#else
+#import <Cocoa/Cocoa.h>
+#endif
+
+#if defined(TARGET_IOS) || defined(TARGET_TVOS)
+
+int main(int argc, char * argv[]) {
+
+#if TARGET_OS_SIMULATOR && (!defined(__IPHONE_13_0) || !defined(__TVOS_13_0))
+#error No simulator support for Metal API for this SDK version. Must build for a device
+#endif
+
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AAPLAppDelegate class]));
+ }
+}
+
+#elif defined(TARGET_MACOS)
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
+
+#endif
diff --git a/tests/projects/objc/metal_app/Application/tvOS/Base.lproj/Main.storyboard b/tests/projects/objc/metal_app/Application/tvOS/Base.lproj/Main.storyboard
new file mode 100644
index 000000000..77bc5bc2d
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/tvOS/Base.lproj/Main.storyboard
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="11762" systemVersion="16E138" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BV1-FR-VrT">
+ <device id="appleTV" orientation="landscape">
+ <adaptation id="light"/>
+ </device>
+ <dependencies>
+ <deployment identifier="tvOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tXr-a1-R10">
+ <objects>
+ <viewController id="BV1-FR-VrT" customClass="AAPLViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="8aa-yV-Osq"/>
+ <viewControllerLayoutGuide type="bottom" id="qHh-Mt-9TT"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="3se-qz-xqx" customClass="MTKView">
+ <rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="SZV-WD-TEh" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/tests/projects/objc/metal_app/Application/tvOS/Info.plist b/tests/projects/objc/metal_app/Application/tvOS/Info.plist
new file mode 100644
index 000000000..63dcd6c1d
--- /dev/null
+++ b/tests/projects/objc/metal_app/Application/tvOS/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>arm64</string>
+ </array>
+ <key>UIUserInterfaceStyle</key>
+ <string>Automatic</string>
+</dict>
+</plist>
diff --git a/tests/projects/objc/metal_app/Configuration/SampleCode.xcconfig b/tests/projects/objc/metal_app/Configuration/SampleCode.xcconfig
new file mode 100644
index 000000000..db86c0698
--- /dev/null
+++ b/tests/projects/objc/metal_app/Configuration/SampleCode.xcconfig
@@ -0,0 +1,13 @@
+//
+// See LICENSE folder for this sample’s licensing information.
+//
+// SampleCode.xcconfig
+//
+
+// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build
+// and run a sample code project. Once you set your project's development team,
+// you'll have a unique bundle identifier. This is because the bundle identifier
+// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this
+// approach in your own projects—it's only useful for sample code projects because
+// they are frequently downloaded and don't have a development team set.
+SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM}
diff --git a/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/.xcodesamplecode.plist b/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/.xcodesamplecode.plist
new file mode 100644
index 000000000..5dd5da85f
--- /dev/null
+++ b/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/.xcodesamplecode.plist
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array/>
+</plist>
diff --git a/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.pbxproj b/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..f1820eccc
--- /dev/null
+++ b/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.pbxproj
@@ -0,0 +1,681 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 3A05CBE01F731ABB00CA21B1 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A1F1B411F0338CF001622B3 /* MetalKit.framework */; };
+ 3A05CBE11F731AC000CA21B1 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A05CBDE1F731AB800CA21B1 /* MetalKit.framework */; };
+ 3A1F1B391F033765001622B3 /* AAPLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A35329C1E99974500C194AD /* AAPLViewController.m */; };
+ 3A1F1B3D1F033827001622B3 /* AAPLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A35329C1E99974500C194AD /* AAPLViewController.m */; };
+ 3A1F1B3E1F033846001622B3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532931E99974500C194AD /* main.m */; };
+ 3A1F1B3F1F033846001622B3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532931E99974500C194AD /* main.m */; };
+ 3A1F1B441F033EF3001622B3 /* AAPLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ACD21341EAE60D2000D1DED /* AAPLAppDelegate.m */; };
+ 3A3532941E99974500C194AD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532931E99974500C194AD /* main.m */; };
+ 3A35329D1E99974500C194AD /* AAPLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A35329C1E99974500C194AD /* AAPLViewController.m */; };
+ 3A3532A01E99974500C194AD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A35329E1E99974500C194AD /* Main.storyboard */; };
+ 3A3532A31E99974500C194AD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A3532A11E99974500C194AD /* LaunchScreen.storyboard */; };
+ 3A3532B91E99974500C194AD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A3532B71E99974500C194AD /* Main.storyboard */; };
+ 3A3532CC1E99974500C194AD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A3532CA1E99974500C194AD /* Main.storyboard */; };
+ 3A3532CE1E99974500C194AD /* AAPLRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532851E99974500C194AD /* AAPLRenderer.m */; };
+ 3A3532CF1E99974500C194AD /* AAPLRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532851E99974500C194AD /* AAPLRenderer.m */; };
+ 3A3532D01E99974500C194AD /* AAPLRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532851E99974500C194AD /* AAPLRenderer.m */; };
+ 3ACD21351EAE60D2000D1DED /* AAPLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ACD21341EAE60D2000D1DED /* AAPLAppDelegate.m */; };
+ 63E77A181ED2059A00E1E542 /* AAPLShaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532871E99974500C194AD /* AAPLShaders.metal */; };
+ 63E77A191ED2059E00E1E542 /* AAPLShaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532871E99974500C194AD /* AAPLShaders.metal */; };
+ 63E77A1A1ED205A200E1E542 /* AAPLShaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 3A3532871E99974500C194AD /* AAPLShaders.metal */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 328A8E964EC41C65EC8AF01A /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE.txt; sourceTree = "<group>"; };
+ 3A05CBDE1F731AB800CA21B1 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = ../../../../iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
+ 3A1F1B411F0338CF001622B3 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = ../../../../AppleTVOS.platform/Developer/SDKs/AppleTVOS11.0.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
+ 3A3532841E99974500C194AD /* AAPLRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AAPLRenderer.h; sourceTree = "<group>"; };
+ 3A3532851E99974500C194AD /* AAPLRenderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AAPLRenderer.m; sourceTree = "<group>"; };
+ 3A3532861E99974500C194AD /* AAPLShaderTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AAPLShaderTypes.h; sourceTree = "<group>"; };
+ 3A3532871E99974500C194AD /* AAPLShaders.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = AAPLShaders.metal; sourceTree = "<group>"; };
+ 3A35328F1E99974500C194AD /* HelloTriangle.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloTriangle.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3A3532931E99974500C194AD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 3A35329B1E99974500C194AD /* AAPLViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AAPLViewController.h; sourceTree = "<group>"; };
+ 3A35329C1E99974500C194AD /* AAPLViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AAPLViewController.m; sourceTree = "<group>"; };
+ 3A35329F1E99974500C194AD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 3A3532A21E99974500C194AD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ 3A3532A41E99974500C194AD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 3A3532A91E99974500C194AD /* HelloTriangle.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloTriangle.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3A3532B81E99974500C194AD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 3A3532BA1E99974500C194AD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 3A3532BF1E99974500C194AD /* HelloTriangle.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloTriangle.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3A3532CB1E99974500C194AD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 3A3532CD1E99974500C194AD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 3ACD21331EAE60D2000D1DED /* AAPLAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AAPLAppDelegate.h; sourceTree = "<group>"; };
+ 3ACD21341EAE60D2000D1DED /* AAPLAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AAPLAppDelegate.m; sourceTree = "<group>"; };
+ 3ED283CC1EC2C6D200A23F58 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
+ 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = SampleCode.xcconfig; path = Configuration/SampleCode.xcconfig; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 3A35328C1E99974500C194AD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3A05CBE11F731AC000CA21B1 /* MetalKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3A3532A61E99974500C194AD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3A05CBE01F731ABB00CA21B1 /* MetalKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3A3532BC1E99974500C194AD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 3A1F1B351F0336A8001622B3 /* iOS */ = {
+ isa = PBXGroup;
+ children = (
+ 3A35329E1E99974500C194AD /* Main.storyboard */,
+ 3A3532A11E99974500C194AD /* LaunchScreen.storyboard */,
+ 3A3532A41E99974500C194AD /* Info.plist */,
+ );
+ path = iOS;
+ sourceTree = "<group>";
+ };
+ 3A1F1B361F0336DB001622B3 /* macOS */ = {
+ isa = PBXGroup;
+ children = (
+ 3A3532CA1E99974500C194AD /* Main.storyboard */,
+ 3A3532CD1E99974500C194AD /* Info.plist */,
+ );
+ path = macOS;
+ sourceTree = "<group>";
+ };
+ 3A1F1B371F0336F4001622B3 /* tvOS */ = {
+ isa = PBXGroup;
+ children = (
+ 3A3532B71E99974500C194AD /* Main.storyboard */,
+ 3A3532BA1E99974500C194AD /* Info.plist */,
+ );
+ path = tvOS;
+ sourceTree = "<group>";
+ };
+ 3A35327E1E99974500C194AD = {
+ isa = PBXGroup;
+ children = (
+ 3ED283CC1EC2C6D200A23F58 /* README.md */,
+ 3A3532831E99974500C194AD /* Renderer */,
+ 3A3532911E99974500C194AD /* Application */,
+ 3AE289861EEA0A9100DF4C9A /* Frameworks */,
+ 3A3532901E99974500C194AD /* Products */,
+ F4F7FAFBBA6575359FC81F34 /* Configuration */,
+ 9772A968083C4C14D4BE84E1 /* LICENSE */,
+ );
+ sourceTree = "<group>";
+ };
+ 3A3532831E99974500C194AD /* Renderer */ = {
+ isa = PBXGroup;
+ children = (
+ 3A3532841E99974500C194AD /* AAPLRenderer.h */,
+ 3A3532851E99974500C194AD /* AAPLRenderer.m */,
+ 3A3532861E99974500C194AD /* AAPLShaderTypes.h */,
+ 3A3532871E99974500C194AD /* AAPLShaders.metal */,
+ );
+ path = Renderer;
+ sourceTree = "<group>";
+ };
+ 3A3532901E99974500C194AD /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 3A35328F1E99974500C194AD /* HelloTriangle.app */,
+ 3A3532A91E99974500C194AD /* HelloTriangle.app */,
+ 3A3532BF1E99974500C194AD /* HelloTriangle.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 3A3532911E99974500C194AD /* Application */ = {
+ isa = PBXGroup;
+ children = (
+ 3ACD21331EAE60D2000D1DED /* AAPLAppDelegate.h */,
+ 3ACD21341EAE60D2000D1DED /* AAPLAppDelegate.m */,
+ 3A35329B1E99974500C194AD /* AAPLViewController.h */,
+ 3A35329C1E99974500C194AD /* AAPLViewController.m */,
+ 3A3532931E99974500C194AD /* main.m */,
+ 3A1F1B361F0336DB001622B3 /* macOS */,
+ 3A1F1B371F0336F4001622B3 /* tvOS */,
+ 3A1F1B351F0336A8001622B3 /* iOS */,
+ );
+ path = Application;
+ sourceTree = "<group>";
+ };
+ 3AE289861EEA0A9100DF4C9A /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 3A05CBDE1F731AB800CA21B1 /* MetalKit.framework */,
+ 3A1F1B411F0338CF001622B3 /* MetalKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 9772A968083C4C14D4BE84E1 /* LICENSE */ = {
+ isa = PBXGroup;
+ children = (
+ 328A8E964EC41C65EC8AF01A /* LICENSE.txt */,
+ );
+ path = LICENSE;
+ sourceTree = "<group>";
+ };
+ F4F7FAFBBA6575359FC81F34 /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */,
+ );
+ name = Configuration;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 3A35328E1E99974500C194AD /* HelloTriangle-iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 3A3532E21E99974500C194AD /* Build configuration list for PBXNativeTarget "HelloTriangle-iOS" */;
+ buildPhases = (
+ 3A35328B1E99974500C194AD /* Sources */,
+ 3A35328C1E99974500C194AD /* Frameworks */,
+ 3A35328D1E99974500C194AD /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "HelloTriangle-iOS";
+ productName = iOS;
+ productReference = 3A35328F1E99974500C194AD /* HelloTriangle.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 3A3532A81E99974500C194AD /* HelloTriangle-tvOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 3A3532E51E99974500C194AD /* Build configuration list for PBXNativeTarget "HelloTriangle-tvOS" */;
+ buildPhases = (
+ 3A3532A51E99974500C194AD /* Sources */,
+ 3A3532A61E99974500C194AD /* Frameworks */,
+ 3A3532A71E99974500C194AD /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "HelloTriangle-tvOS";
+ productName = tvOS;
+ productReference = 3A3532A91E99974500C194AD /* HelloTriangle.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 3A3532BE1E99974500C194AD /* HelloTriangle-macOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 3A3532E81E99974500C194AD /* Build configuration list for PBXNativeTarget "HelloTriangle-macOS" */;
+ buildPhases = (
+ 3A3532BB1E99974500C194AD /* Sources */,
+ 3A3532BC1E99974500C194AD /* Frameworks */,
+ 3A3532BD1E99974500C194AD /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "HelloTriangle-macOS";
+ productName = macOS;
+ productReference = 3A3532BF1E99974500C194AD /* HelloTriangle.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 3A35327F1E99974500C194AD /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1200;
+ ORGANIZATIONNAME = Apple;
+ TargetAttributes = {
+ 3A35328E1E99974500C194AD = {
+ CreatedOnToolsVersion = 8.3;
+ ProvisioningStyle = Automatic;
+ };
+ 3A3532A81E99974500C194AD = {
+ CreatedOnToolsVersion = 8.3;
+ ProvisioningStyle = Automatic;
+ };
+ 3A3532BE1E99974500C194AD = {
+ CreatedOnToolsVersion = 8.3;
+ DevelopmentTeam = 43AAQM58X3;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = 3A3532821E99974500C194AD /* Build configuration list for PBXProject "HelloTriangle" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 3A35327E1E99974500C194AD;
+ productRefGroup = 3A3532901E99974500C194AD /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 3A3532BE1E99974500C194AD /* HelloTriangle-macOS */,
+ 3A35328E1E99974500C194AD /* HelloTriangle-iOS */,
+ 3A3532A81E99974500C194AD /* HelloTriangle-tvOS */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 3A35328D1E99974500C194AD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3A3532A01E99974500C194AD /* Main.storyboard in Resources */,
+ 3A3532A31E99974500C194AD /* LaunchScreen.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3A3532A71E99974500C194AD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3A3532B91E99974500C194AD /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3A3532BD1E99974500C194AD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3A3532CC1E99974500C194AD /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 3A35328B1E99974500C194AD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63E77A181ED2059A00E1E542 /* AAPLShaders.metal in Sources */,
+ 3A35329D1E99974500C194AD /* AAPLViewController.m in Sources */,
+ 3A3532941E99974500C194AD /* main.m in Sources */,
+ 3A3532CE1E99974500C194AD /* AAPLRenderer.m in Sources */,
+ 3ACD21351EAE60D2000D1DED /* AAPLAppDelegate.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3A3532A51E99974500C194AD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 63E77A191ED2059E00E1E542 /* AAPLShaders.metal in Sources */,
+ 3A3532CF1E99974500C194AD /* AAPLRenderer.m in Sources */,
+ 3A1F1B391F033765001622B3 /* AAPLViewController.m in Sources */,
+ 3A1F1B3F1F033846001622B3 /* main.m in Sources */,
+ 3A1F1B441F033EF3001622B3 /* AAPLAppDelegate.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 3A3532BB1E99974500C194AD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3A1F1B3D1F033827001622B3 /* AAPLViewController.m in Sources */,
+ 63E77A1A1ED205A200E1E542 /* AAPLShaders.metal in Sources */,
+ 3A1F1B3E1F033846001622B3 /* main.m in Sources */,
+ 3A3532D01E99974500C194AD /* AAPLRenderer.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 3A35329E1E99974500C194AD /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 3A35329F1E99974500C194AD /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ 3A3532A11E99974500C194AD /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 3A3532A21E99974500C194AD /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+ 3A3532B71E99974500C194AD /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 3A3532B81E99974500C194AD /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ 3A3532CA1E99974500C194AD /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 3A3532CB1E99974500C194AD /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 3A3532E01E99974500C194AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = HelloTriangle;
+ };
+ name = Debug;
+ };
+ 3A3532E11E99974500C194AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_NAME = HelloTriangle;
+ };
+ name = Release;
+ };
+ 3A3532E31E99974500C194AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)/System/Library/Frameworks",
+ );
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(inherited)",
+ TARGET_IOS,
+ );
+ INFOPLIST_FILE = Application/iOS/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.HelloTriangle${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = HelloTriangle;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 3A3532E41E99974500C194AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)/System/Library/Frameworks",
+ );
+ GCC_PREPROCESSOR_DEFINITIONS = TARGET_IOS;
+ INFOPLIST_FILE = Application/iOS/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.HelloTriangle${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = HelloTriangle;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 3A3532E61E99974500C194AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)/System/Library/Frameworks",
+ );
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ TARGET_TVOS,
+ "$(inherited)",
+ );
+ INFOPLIST_FILE = Application/tvOS/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.HelloTriangle${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = HelloTriangle;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = appletvos;
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 12.0;
+ };
+ name = Debug;
+ };
+ 3A3532E71E99974500C194AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SDKROOT)/System/Library/Frameworks",
+ );
+ GCC_PREPROCESSOR_DEFINITIONS = TARGET_TVOS;
+ INFOPLIST_FILE = Application/tvOS/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.HelloTriangle${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = HelloTriangle;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = appletvos;
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 12.0;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 3A3532E91E99974500C194AD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Mac Developer";
+ COMBINE_HIDPI_IMAGES = YES;
+ DEVELOPMENT_TEAM = 43AAQM58X3;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(inherited)",
+ TARGET_MACOS,
+ );
+ INFOPLIST_FILE = Application/macOS/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.$(PRODUCT_NAME)${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = HelloTriangle;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 3A3532EA1E99974500C194AD /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 907FE32A28789CDAFD777257 /* SampleCode.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Mac Developer";
+ COMBINE_HIDPI_IMAGES = YES;
+ DEVELOPMENT_TEAM = 43AAQM58X3;
+ GCC_PREPROCESSOR_DEFINITIONS = TARGET_MACOS;
+ INFOPLIST_FILE = Application/macOS/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.$(PRODUCT_NAME)${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = HelloTriangle;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 3A3532821E99974500C194AD /* Build configuration list for PBXProject "HelloTriangle" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3A3532E01E99974500C194AD /* Debug */,
+ 3A3532E11E99974500C194AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 3A3532E21E99974500C194AD /* Build configuration list for PBXNativeTarget "HelloTriangle-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3A3532E31E99974500C194AD /* Debug */,
+ 3A3532E41E99974500C194AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 3A3532E51E99974500C194AD /* Build configuration list for PBXNativeTarget "HelloTriangle-tvOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3A3532E61E99974500C194AD /* Debug */,
+ 3A3532E71E99974500C194AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 3A3532E81E99974500C194AD /* Build configuration list for PBXNativeTarget "HelloTriangle-macOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3A3532E91E99974500C194AD /* Debug */,
+ 3A3532EA1E99974500C194AD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 3A35327F1E99974500C194AD /* Project object */;
+}
diff --git a/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 000000000..3ddf867a1
--- /dev/null
+++ b/tests/projects/objc/metal_app/HelloTriangle.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>BuildSystemType</key>
+ <string>Latest</string>
+</dict>
+</plist>
diff --git a/tests/projects/objc/metal_app/LICENSE/LICENSE.txt b/tests/projects/objc/metal_app/LICENSE/LICENSE.txt
new file mode 100644
index 000000000..e11438f78
--- /dev/null
+++ b/tests/projects/objc/metal_app/LICENSE/LICENSE.txt
@@ -0,0 +1,8 @@
+Copyright © 2020 Apple Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/tests/projects/objc/metal_app/README.md b/tests/projects/objc/metal_app/README.md
new file mode 100644
index 000000000..050a1611b
--- /dev/null
+++ b/tests/projects/objc/metal_app/README.md
@@ -0,0 +1,332 @@
+# Using a Render Pipeline to Render Primitives
+
+Render a simple 2D triangle.
+
+## Overview
+
+In [Using Metal to Draw a View’s Contents](https://developer.apple.com/documentation/metal/basic_tasks_and_concepts/using_metal_to_draw_a_view_s_contents), you learned how to set up an `MTKView` object and to change the view's contents using a render pass.
+That sample simply erased the view's contents to a background color.
+This sample shows you how to configure a render pipeline and use it as part of the render pass to draw a simple 2D colored triangle into the view.
+The sample supplies a position and color for each vertex, and the render pipeline uses that data to render the triangle, interpolating color values between the colors specified for the triangle's vertices.
+
+![Simple 2D Triangle Vertices](Documentation/2DTriangleVertices.png)
+
+The Xcode project contains schemes for running the sample on macOS, iOS, and tvOS.
+
+## Understand the Metal Render Pipeline
+
+A *render pipeline* processes drawing commands and writes data into a render pass’s targets.
+ A render pipeline has many stages, some programmed using shaders and others with fixed or configurable behavior.
+This sample focuses on the three main stages of the pipeline: the vertex stage, the rasterization stage, and the fragment stage.
+The vertex stage and fragment stage are programmable, so you write functions for them in Metal Shading Language (MSL).
+The rasterization stage has fixed behavior.
+
+**Figure 1** Main stages of the Metal graphics render pipeline
+![Main Stages of the Metal Graphics Render Pipeline](Documentation/SimplePipeline.png)
+
+Rendering starts with a drawing command, which includes a vertex count and what kind of primitive to render. For example, here's the drawing command from this sample:
+
+``` objective-c
+// Draw the triangle.
+[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
+ vertexStart:0
+ vertexCount:3];
+```
+
+The vertex stage provides data for each vertex. When enough vertices have been processed, the render pipeline rasterizes the primitive, determining which pixels in the render targets lie within the boundaries of the primitive. The fragment stage determines the values to write into the render targets for those pixels.
+
+In the rest of this sample, you will see how to write the vertex and fragment functions, how to create the render pipeline state object, and finally, how to encode a draw command that uses this pipeline.
+
+## Decide How Data is Processed by Your Custom Render Pipeline
+
+A vertex function generates data for a single vertex and a fragment function generates data for a single fragment, but you decide how they work.
+You configure the stages of the pipeline with a goal in mind, meaning that you know what you want the pipeline to generate and how it generates those results.
+
+Decide what data to pass into your render pipeline and what data is passed to later stages of the pipeline. There are typically three places where you do this:
+
+- The inputs to the pipeline, which are provided by your app and passed to the vertex stage.
+- The outputs of the vertex stage, which is passed to the rasterization stage.
+- The inputs to the fragment stage, which are provided by your app or generated by the rasterization stage.
+
+In this sample, the input data for the pipeline is the position of a vertex and its color. To demonstrate the kind of transformation you typically perform in a vertex function, input coordinates are defined in a custom coordinate space, measured in pixels from the center of the view. These coordinates need to be translated into Metal's coordinate system.
+
+Declare an `AAPLVertex` structure, using SIMD vector types to hold the position and color data.
+To share a single definition for how the structure is laid out in memory, declare the structure in a common header and import it in both the Metal shader and the app.
+
+``` objective-c
+typedef struct
+{
+ vector_float2 position;
+ vector_float4 color;
+} AAPLVertex;
+```
+
+SIMD types are commonplace in Metal Shading Language, and you should also use them in your app using the simd library.
+SIMD types contain multiple channels of a particular data type, so declaring the position as a `vector_float2` means it contains two 32-bit float values (which will hold the x and y coordinates.)
+Colors are stored using a `vector_float4`, so they have four channels – red, green, blue, and alpha.
+
+In the app, the input data is specified using a constant array:
+
+``` objective-c
+static const AAPLVertex triangleVertices[] =
+{
+ // 2D positions, RGBA colors
+ { { 250, -250 }, { 1, 0, 0, 1 } },
+ { { -250, -250 }, { 0, 1, 0, 1 } },
+ { { 0, 250 }, { 0, 0, 1, 1 } },
+};
+```
+
+The vertex stage generates data for a vertex, so it needs to provide a color and a transformed position.
+Declare a `RasterizerData` structure containing a position and a color value, again using SIMD types.
+
+``` metal
+struct RasterizerData
+{
+ // The [[position]] attribute of this member indicates that this value
+ // is the clip space position of the vertex when this structure is
+ // returned from the vertex function.
+ float4 position [[position]];
+
+ // Since this member does not have a special attribute, the rasterizer
+ // interpolates its value with the values of the other triangle vertices
+ // and then passes the interpolated value to the fragment shader for each
+ // fragment in the triangle.
+ float4 color;
+};
+```
+
+The output position (described in detail below) must be defined as a `vector_float4`. The color is declared as it was in the input data structure.
+
+You need to tell Metal which field in the rasterization data provides position data, because Metal doesn't enforce any particular naming convention for fields in your struct.
+Annotate the `position` field with the `[[position]]` attribute qualifier to declare that this field holds the output position.
+
+The fragment function simply passes the rasterization stage's data to later stages so it doesn't need any additional arguments.
+
+## Declare the Vertex Function
+
+Declare the vertex function, including its input arguments and the data it outputs.
+Much like compute functions were declared using the `kernel` keyword, you declare a vertex function using the `vertex` keyword.
+
+``` metal
+vertex RasterizerData
+vertexShader(uint vertexID [[vertex_id]],
+ constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],
+ constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])
+```
+
+The first argument, `vertexID`, uses the `[[vertex_id]]` attribute qualifier, which is another Metal keyword.
+When you execute a render command, the GPU calls your vertex function multiple times, generating a unique value for each vertex.
+
+The second argument, `vertices`, is an array that contains the vertex data, using the `AAPLVertex` struct previously defined.
+
+To transform the position into Metal's coordinates, the function needs the size of the viewport (in pixels) that the triangle is being drawn into, so this is stored in the `viewportSizePointer` argument.
+
+The second and third arguments have the `[[buffer(n)]]` attribute qualifier.
+By default, Metal assigns slots in the argument table for each parameter automatically.
+When you add the `[[buffer(n)]]` qualifier to a buffer argument, you tell Metal explicitly which slot to use.
+Declaring slots explicitly can make it easier to revise your shaders without also needing to change your app code.
+Declare the constants for the two indicies in the shared header file.
+
+The function's output is a `RasterizerData` struct.
+
+## Write the Vertex Function
+
+Your vertex function must generate both fields of the output struct.
+Use the `vertexID` argument to index into the `vertices` array and read the input data for the vertex.
+Also, retrieve the viewport dimensions.
+
+``` metal
+float2 pixelSpacePosition = vertices[vertexID].position.xy;
+
+// Get the viewport size and cast to float.
+vector_float2 viewportSize = vector_float2(*viewportSizePointer);
+
+```
+
+Vertex functions must provide position data in *clip-space coordinates*, which are 3D points specified using a four-dimensional homogenous vector (`x,y,z,w`). The rasterization stage takes the output position and divides the `x`,`y`, and `z` coordinates by `w` to generate a 3D point in *normalized device coordinates*. Normalized device coordinates are independent of viewport size.
+
+**Figure 2** Normalized device coordinate system
+![Normalized device coordinate system](Documentation/normalizeddevicecoords.png)
+
+Normalized device coordinates use a *left-handed coordinate system* and map to positions in the viewport.
+Primitives are clipped to a box in this coordinate system and then rasterized.
+The lower-left corner of the clipping box is at an `(x,y)` coordinate of `(-1.0,-1.0)` and the upper-right corner is at `(1.0,1.0)`.
+Positive-z values point away from the camera (into the screen.)
+The visible portion of the `z` coordinate is between `0.0` (the near clipping plane) and `1.0` (the far clipping plane).
+
+Transform the input coordinate system to the normalized device coordinate system.
+
+![Vertex function coordinate transformation](Documentation/metal-coordinate-transformation.png)
+
+Because this is a 2D application and does not need homogenous coordinates, first write a default value to the output coordinate, with the the `w` value is set to `1.0` and the other coordinates set to `0.0`.
+This means that the coordinates are already in the normalized device coordinate space and the vertex function should generate (x,y) coordinates in that coordinate space.
+Divide the input position by half the viewport size to generate normalized device coordinates.
+Since this calculation is performed using SIMD types, both channels can be divided at the same time using a single line of code.
+Perform the divide and put the results in the x and y channels of the output position.
+
+``` metal
+out.position = vector_float4(0.0, 0.0, 0.0, 1.0);
+out.position.xy = pixelSpacePosition / (viewportSize / 2.0);
+```
+
+Finally, copy the color value into the `out.color` return value.
+
+``` metal
+out.color = vertices[vertexID].color;
+```
+
+## Write a Fragment Function
+
+A *fragment* is a possible change to the render targets. The rasterizer determines which pixels of the render target are covered by the primitive.
+Only fragments whose pixel centers are inside the triangle are rendered.
+
+**Figure 3** Fragments generated by the rasterization stage
+![Fragments generated by the rasterization stage](Documentation/Rasterization.png)
+
+A fragment function processes incoming information from the rasterizer for a single position and calculates output values for each of the render targets. These fragment values are processed by later stages in the pipeline, eventually being written to the render targets.
+
+- Note: The reason a fragment is called a possible change is because the pipeline stages after the fragment stage can be configured to reject some fragments or change what gets written to the render targets. In this sample, all values calculated by the fragment stage are written as-is to the render target.
+
+The fragment shader in this sample receives the same parameters that were declared in the vertex shader's output. Declare the fragment function using the `fragment` keyword. It takes a single argument, the same `RasterizerData` structure that was provided by the vertex stage. Add the `[[stage_in]]` attribute qualifier to indicate that this argument is generated by the rasterizer.
+
+``` metal
+fragment float4 fragmentShader(RasterizerData in [[stage_in]])
+```
+
+If your fragment function writes to multiple render targets, it must declare a struct with fields for each render target.
+Because this sample only has a single render target, you specify a floating-point vector directly as the function's output. This output is the color to be written to the render target.
+
+The rasterization stage calculates values for each fragment's arguments and calls the fragment function with them.
+The rasterization stage calculates its color argument as a blend of the colors at the triangle's vertices.
+The closer a fragment is to a vertex, the more that vertex contributes to the final color.
+
+**Figure 4** Interpolated fragment colors
+![Interpolated Fragment Colors](Documentation/Interpolation.png)
+
+Return the interpolated color as the function's output.
+
+``` metal
+return in.color;
+```
+
+## Create a Render Pipeline State Object
+
+Now that the functions are complete, you can create a render pipeline that uses them.
+First, get the default library and obtain a [`MTLFunction`][MTLFunction] object for each function.
+
+``` objective-c
+id<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
+
+id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
+id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
+```
+
+Next, create a [`MTLRenderPipelineState`][MTLRenderPipelineState] object.
+Render pipelines have more stages to configure, so you use a [`MTLRenderPipelineDescriptor`][MTLRenderPipelineDescriptor] to configure the pipeline.
+
+``` objective-c
+MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
+pipelineStateDescriptor.label = @"Simple Pipeline";
+pipelineStateDescriptor.vertexFunction = vertexFunction;
+pipelineStateDescriptor.fragmentFunction = fragmentFunction;
+pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
+
+_pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor
+ error:&error];
+```
+
+In addition to specifying the vertex and fragment functions, you also declare the *pixel format* of all render targets that the pipeline will draw into.
+A pixel format ([`MTLPixelFormat`][MTLPixelFormat]) defines the memory layout of pixel data.
+For simple formats, this definition includes the number of bytes per pixel, the number of channels of data stored in a pixel, and the bit layout of those channels.
+Since this sample only has one render target and it is provided by the view, copy the view's pixel format into the render pipeline descriptor.
+Your render pipeline state must use a pixel format that is compatible with the one specified by the render pass.
+In this sample, the render pass and the pipeline state object both use the view's pixel format, so they are always the same.
+
+When Metal creates the render pipeline state object, the pipeline is configured to convert the fragment function's output into the render target's pixel format.
+If you want to target a different pixel format, you need to create a different pipeline state object.
+You can reuse the same shaders in multiple pipelines targeting different pixel formats.
+
+
+## Set a Viewport
+
+Now that you have the render pipeline state object for the pipeline, you'll render the triangle. You do this using a render command encoder. First, set the viewport, so that Metal knows which part of the render target you want to draw into.
+
+``` objective-c
+// Set the region of the drawable to draw into.
+[renderEncoder setViewport:(MTLViewport){0.0, 0.0, _viewportSize.x, _viewportSize.y, 0.0, 1.0 }];
+```
+
+## Set the Render Pipeline State
+
+Set the render pipeline state for the pipeline you want to use.
+
+``` objective-c
+[renderEncoder setRenderPipelineState:_pipelineState];
+```
+
+## Send Argument Data to the Vertex Function
+
+Often, you use buffers ([`MTLBuffer`][MTLBuffer]) to pass data to shaders.
+However, when you need to pass only a small amount of data to the vertex function, as is the case here, copy the data directly into the command buffer.
+
+The sample copies data for both parameters into the command buffer.
+The vertex data is copied from an array defined in the sample.
+The viewport data is copied from the same variable that you used to set the viewport.
+
+In this sample, the fragment function uses only the data it receives from the rasterizer, so there are no arguments to set.
+
+``` objective-c
+[renderEncoder setVertexBytes:triangleVertices
+ length:sizeof(triangleVertices)
+ atIndex:AAPLVertexInputIndexVertices];
+
+[renderEncoder setVertexBytes:&_viewportSize
+ length:sizeof(_viewportSize)
+ atIndex:AAPLVertexInputIndexViewportSize];
+```
+
+
+## Encode the Drawing Command
+
+Specify the kind of primitive, the starting index, and the number of vertices.
+When the triangle is rendered, the vertex function is called with values of 0, 1, and 2 for the `vertexID` argument.
+
+``` objective-c
+// Draw the triangle.
+[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
+ vertexStart:0
+ vertexCount:3];
+```
+
+As with Drawing to the Screen Using Metal, you end the encoding process and commit the command buffer.
+However, you could encode more render commands using the same set of steps.
+The final image is rendered as if the commands were processed in the order they were specified.
+(For performance, the GPU is allowed to process commands or even parts of commands in parallel, so long as the final result appears to have been rendered in order. )
+
+## Experiment with the Color Interpolation
+
+In this sample, color values were interpolated across the triangle.
+That's often what you want, but sometimes you want a value to be generated by one vertex and remain constant across the whole primitive.
+Specify the `flat` attribute qualifier on an output of the vertex function to do this.
+Try this now.
+Find the definition of `RasterizerData` in the sample project and add the `[[flat]]` qualifier to its `color` field.
+
+`float4 color [[flat]];`
+
+Run the sample again.
+The render pipeline uses the color value from the first vertex (called the *provoking vertex*) uniformly across the triangle, and it ignores the colors from the other two vertices.
+You can use a mix of flat shaded and interpolated values, simply by adding or omitting the `flat` qualifier on your vertex function's outputs.
+The [Metal Shading Language specification][ShadingLanguageSpec] defines other attribute qualifiers you can also use to modify the rasterization behavior.
+
+[ScreenDrawing]: https://developer.apple.com/documentation/metal
+[MTLDevice]: https://developer.apple.com/documentation/metal/mtldevice
+[MTLResource]: https://developer.apple.com/documentation/metal/mtlresource
+[MTLBuffer]: https://developer.apple.com/documentation/metal/mtlbuffer
+[MTLRenderPipelineState]: https://developer.apple.com/documentation/metal/mtlrenderpipelinestate
+[MTLRenderPipelineDescriptor]: https://developer.apple.com/documentation/metal/mtlrenderpipelinedescriptor
+[MTLRenderCommandEncoder]: https://developer.apple.com/documentation/metal/mtlrendercommandencoder
+[MTLPixelFormat]: https://developer.apple.com/documentation/metal/mtlpixelformat
+[MTKView]: https://developer.apple.com/documentation/metalkit/mtkview
+[ShadingLanguageSpec]: https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
+[MTLFunction]: https://developer.apple.com/documentation/metal/mtlfunction
diff --git a/tests/projects/objc/metal_app/Renderer/AAPLRenderer.h b/tests/projects/objc/metal_app/Renderer/AAPLRenderer.h
new file mode 100644
index 000000000..f7bcba51d
--- /dev/null
+++ b/tests/projects/objc/metal_app/Renderer/AAPLRenderer.h
@@ -0,0 +1,14 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Header for a platform independent renderer class, which performs Metal setup and per frame rendering.
+*/
+
+@import MetalKit;
+
+@interface AAPLRenderer : NSObject<MTKViewDelegate>
+
+- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView;
+
+@end
diff --git a/tests/projects/objc/metal_app/Renderer/AAPLRenderer.m b/tests/projects/objc/metal_app/Renderer/AAPLRenderer.m
new file mode 100644
index 000000000..6cfc2cc0a
--- /dev/null
+++ b/tests/projects/objc/metal_app/Renderer/AAPLRenderer.m
@@ -0,0 +1,132 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Implementation of a platform independent renderer class, which performs Metal setup and per frame rendering
+*/
+
+@import simd;
+@import MetalKit;
+
+#import "AAPLRenderer.h"
+
+// Header shared between C code here, which executes Metal API commands, and .metal files, which
+// uses these types as inputs to the shaders.
+#import "AAPLShaderTypes.h"
+
+// Main class performing the rendering
+@implementation AAPLRenderer
+{
+ id<MTLDevice> _device;
+
+ // The render pipeline generated from the vertex and fragment shaders in the .metal shader file.
+ id<MTLRenderPipelineState> _pipelineState;
+
+ // The command queue used to pass commands to the device.
+ id<MTLCommandQueue> _commandQueue;
+
+ // The current size of the view, used as an input to the vertex shader.
+ vector_uint2 _viewportSize;
+}
+
+- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView
+{
+ self = [super init];
+ if(self)
+ {
+ NSError *error;
+
+ _device = mtkView.device;
+
+ // Load all the shader files with a .metal file extension in the project.
+ id<MTLLibrary> defaultLibrary = [_device newDefaultLibrary];
+
+ id<MTLFunction> vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
+ id<MTLFunction> fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
+
+ // Configure a pipeline descriptor that is used to create a pipeline state.
+ MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
+ pipelineStateDescriptor.label = @"Simple Pipeline";
+ pipelineStateDescriptor.vertexFunction = vertexFunction;
+ pipelineStateDescriptor.fragmentFunction = fragmentFunction;
+ pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
+
+ _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor
+ error:&error];
+
+ // Pipeline State creation could fail if the pipeline descriptor isn't set up properly.
+ // If the Metal API validation is enabled, you can find out more information about what
+ // went wrong. (Metal API validation is enabled by default when a debug build is run
+ // from Xcode.)
+ NSAssert(_pipelineState, @"Failed to create pipeline state: %@", error);
+
+ // Create the command queue
+ _commandQueue = [_device newCommandQueue];
+ }
+
+ return self;
+}
+
+/// Called whenever view changes orientation or is resized
+- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
+{
+ // Save the size of the drawable to pass to the vertex shader.
+ _viewportSize.x = size.width;
+ _viewportSize.y = size.height;
+}
+
+/// Called whenever the view needs to render a frame.
+- (void)drawInMTKView:(nonnull MTKView *)view
+{
+ static const AAPLVertex triangleVertices[] =
+ {
+ // 2D positions, RGBA colors
+ { { 250, -250 }, { 1, 0, 0, 1 } },
+ { { -250, -250 }, { 0, 1, 0, 1 } },
+ { { 0, 250 }, { 0, 0, 1, 1 } },
+ };
+
+ // Create a new command buffer for each render pass to the current drawable.
+ id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
+ commandBuffer.label = @"MyCommand";
+
+ // Obtain a renderPassDescriptor generated from the view's drawable textures.
+ MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
+
+ if(renderPassDescriptor != nil)
+ {
+ // Create a render command encoder.
+ id<MTLRenderCommandEncoder> renderEncoder =
+ [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
+ renderEncoder.label = @"MyRenderEncoder";
+
+ // Set the region of the drawable to draw into.
+ [renderEncoder setViewport:(MTLViewport){0.0, 0.0, _viewportSize.x, _viewportSize.y, 0.0, 1.0 }];
+
+ [renderEncoder setRenderPipelineState:_pipelineState];
+
+ // Pass in the parameter data.
+ [renderEncoder setVertexBytes:triangleVertices
+ length:sizeof(triangleVertices)
+ atIndex:AAPLVertexInputIndexVertices];
+
+ [renderEncoder setVertexBytes:&_viewportSize
+ length:sizeof(_viewportSize)
+ atIndex:AAPLVertexInputIndexViewportSize];
+
+ // Draw the triangle.
+ [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
+ vertexStart:0
+ vertexCount:3];
+
+ [renderEncoder endEncoding];
+
+ // Schedule a present once the framebuffer is complete using the current drawable.
+ [commandBuffer presentDrawable:view.currentDrawable];
+ }
+
+ // Finalize rendering here & push the command buffer to the GPU.
+ [commandBuffer commit];
+}
+
+@end
diff --git a/tests/projects/objc/metal_app/Renderer/AAPLShaderTypes.h b/tests/projects/objc/metal_app/Renderer/AAPLShaderTypes.h
new file mode 100644
index 000000000..b3355f911
--- /dev/null
+++ b/tests/projects/objc/metal_app/Renderer/AAPLShaderTypes.h
@@ -0,0 +1,31 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Header containing types and enum constants shared between Metal shaders and C/ObjC source
+*/
+
+#ifndef AAPLShaderTypes_h
+#define AAPLShaderTypes_h
+
+#include <simd/simd.h>
+
+// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs
+// match Metal API buffer set calls.
+typedef enum AAPLVertexInputIndex
+{
+ AAPLVertexInputIndexVertices = 0,
+ AAPLVertexInputIndexViewportSize = 1,
+} AAPLVertexInputIndex;
+
+// This structure defines the layout of vertices sent to the vertex
+// shader. This header is shared between the .metal shader and C code, to guarantee that
+// the layout of the vertex array in the C code matches the layout that the .metal
+// vertex shader expects.
+typedef struct
+{
+ vector_float2 position;
+ vector_float4 color;
+} AAPLVertex;
+
+#endif /* AAPLShaderTypes_h */
diff --git a/tests/projects/objc/metal_app/Renderer/AAPLShaders.metal b/tests/projects/objc/metal_app/Renderer/AAPLShaders.metal
new file mode 100644
index 000000000..62b05cf71
--- /dev/null
+++ b/tests/projects/objc/metal_app/Renderer/AAPLShaders.metal
@@ -0,0 +1,62 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Metal shaders used for this sample
+*/
+
+#include <metal_stdlib>
+
+using namespace metal;
+
+// Include header shared between this Metal shader code and C code executing Metal API commands.
+#include "AAPLShaderTypes.h"
+
+// Vertex shader outputs and fragment shader inputs
+struct RasterizerData
+{
+ // The [[position]] attribute of this member indicates that this value
+ // is the clip space position of the vertex when this structure is
+ // returned from the vertex function.
+ float4 position [[position]];
+
+ // Since this member does not have a special attribute, the rasterizer
+ // interpolates its value with the values of the other triangle vertices
+ // and then passes the interpolated value to the fragment shader for each
+ // fragment in the triangle.
+ float4 color;
+};
+
+vertex RasterizerData
+vertexShader(uint vertexID [[vertex_id]],
+ constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],
+ constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])
+{
+ RasterizerData out;
+
+ // Index into the array of positions to get the current vertex.
+ // The positions are specified in pixel dimensions (i.e. a value of 100
+ // is 100 pixels from the origin).
+ float2 pixelSpacePosition = vertices[vertexID].position.xy;
+
+ // Get the viewport size and cast to float.
+ vector_float2 viewportSize = vector_float2(*viewportSizePointer);
+
+
+ // To convert from positions in pixel space to positions in clip-space,
+ // divide the pixel coordinates by half the size of the viewport.
+ out.position = vector_float4(0.0, 0.0, 0.0, 1.0);
+ out.position.xy = pixelSpacePosition / (viewportSize / 2.0);
+
+ // Pass the input color directly to the rasterizer.
+ out.color = vertices[vertexID].color;
+
+ return out;
+}
+
+fragment float4 fragmentShader(RasterizerData in [[stage_in]])
+{
+ // Return the interpolated color.
+ return in.color;
+}
+
diff --git a/tests/projects/objc/metal_app/xmake.lua b/tests/projects/objc/metal_app/xmake.lua
new file mode 100644
index 000000000..2a808a5fb
--- /dev/null
+++ b/tests/projects/objc/metal_app/xmake.lua
@@ -0,0 +1,22 @@
+add_rules("mode.debug", "mode.release")
+
+target("HelloTriangle")
+ add_rules("xcode.application")
+ add_includedirs("Renderer")
+ add_frameworks("MetalKit")
+ add_mflags("-fmodules")
+ add_files("Renderer/*.m", "Renderer/*.metal")
+ if is_plat("macosx") then
+ add_files("Application/main.m")
+ add_files("Application/AAPLViewController.m")
+ add_files("Application/macOS/Info.plist")
+ add_files("Application/macOS/Base.lproj/*.storyboard")
+ add_defines("TARGET_MACOS")
+ add_frameworks("AppKit")
+ elseif is_plat("iphoneos") then
+ add_files("Application/*.m")
+ add_files("Application/iOS/Info.plist")
+ add_files("Application/iOS/Base.lproj/*.storyboard")
+ add_frameworks("UIKit")
+ add_defines("TARGET_IOS")
+ end
diff --git a/tests/projects/openmp/hello/xmake.lua b/tests/projects/openmp/hello/xmake.lua
index c1f837287..db12f0487 100644
--- a/tests/projects/openmp/hello/xmake.lua
+++ b/tests/projects/openmp/hello/xmake.lua
@@ -1,6 +1,5 @@
-add_requires("libomp", {optional = true})
+add_requires("openmp")
target("hello")
set_kind("binary")
add_files("src/*.c")
- add_rules("c.openmp")
- add_packages("libomp")
+ add_packages("openmp")
diff --git a/tests/projects/openmp/loop/xmake.lua b/tests/projects/openmp/loop/xmake.lua
index eb14be1a3..e1d0ab721 100644
--- a/tests/projects/openmp/loop/xmake.lua
+++ b/tests/projects/openmp/loop/xmake.lua
@@ -1,6 +1,5 @@
-add_requires("libomp", {optional = true})
+add_requires("openmp")
target("loop")
set_kind("binary")
add_files("src/*.cpp")
- add_rules("c++.openmp")
- add_packages("libomp")
+ add_packages("openmp")
diff --git a/tests/projects/other/bin2c/xmake.lua b/tests/projects/other/bin2c/xmake.lua
index b5517a54e..b4c71e705 100644
--- a/tests/projects/other/bin2c/xmake.lua
+++ b/tests/projects/other/bin2c/xmake.lua
@@ -2,9 +2,9 @@ add_rules("mode.debug", "mode.release")
target("test")
set_kind("binary")
- add_rules("utils.bin2c", {linewidth = 16})
+ add_rules("utils.bin2c", {linewidth = 16, extensions = {".bin", ".png"}})
add_files("src/*.c")
add_files("src/*.bin")
- add_files("src/*.png", {rules = "utils.bin2c"})
+ add_files("src/*.png")
diff --git a/tests/projects/other/build_deps/xmake.lua b/tests/projects/other/build_deps/xmake.lua
index 2458ba7df..9fe31c900 100644
--- a/tests/projects/other/build_deps/xmake.lua
+++ b/tests/projects/other/build_deps/xmake.lua
@@ -4,7 +4,7 @@ target("dep1")
set_kind("static")
add_deps("dep3")
add_files("src/interface.c")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
os.rm(target:dep("dep3"):targetfile())
end)
@@ -20,7 +20,7 @@ target("dep2")
set_kind("static")
add_deps("dep3")
add_files("src/interface.c")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
os.rm(target:dep("dep3"):targetfile())
end)
@@ -36,7 +36,7 @@ target("dep3")
set_kind("static")
add_files("src/interface.c")
add_deps("dep4", "dep5")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
os.rm(target:dep("dep4"):targetfile())
os.rm(target:dep("dep5"):targetfile())
@@ -51,7 +51,7 @@ target("dep3")
target("dep4")
set_kind("static")
add_files("src/interface.c")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
end)
after_link(function (target)
@@ -62,7 +62,7 @@ target("dep4")
target("dep5")
set_kind("static")
add_files("src/interface.c")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
end)
after_link(function (target)
@@ -74,7 +74,7 @@ target("test1")
set_kind("binary")
add_deps("dep1", "dep2")
add_files("src/test.c")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
os.rm(target:dep("dep1"):targetfile())
os.rm(target:dep("dep2"):targetfile())
@@ -94,7 +94,7 @@ target("test2")
set_kind("binary")
add_deps("dep1")
add_files("src/test.c")
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
os.rm(target:dep("dep1"):targetfile())
os.rm(target:dep("dep3"):targetfile())
@@ -120,7 +120,7 @@ target("test3")
add_rules("test3")
add_files("src/test.c")
set_policy("build.across_targets_in_parallel", false)
- on_load(function (target)
+ after_load(function (target)
os.rm(target:targetfile())
os.rm(target:dep("dep1"):targetfile())
os.rm(target:dep("dep3"):targetfile())
diff --git a/tests/projects/other/glsl2spv/.gitignore b/tests/projects/other/glsl2spv/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/other/glsl2spv/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/other/glsl2spv/src/main.c b/tests/projects/other/glsl2spv/src/main.c
new file mode 100644
index 000000000..56e54d771
--- /dev/null
+++ b/tests/projects/other/glsl2spv/src/main.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+static unsigned char g_test_vert_spv_data[] = {
+ #include "test.vert.spv.h"
+};
+
+static unsigned char g_test_frag_spv_data[] = {
+ #include "test.frag.spv.h"
+};
+
+int main(int argc, char** argv)
+{
+ printf("test.vert.spv: %s, size: %d\n", g_test_vert_spv_data, (int)sizeof(g_test_vert_spv_data));
+ printf("test.frag.spv: %s, size: %d\n", g_test_frag_spv_data, (int)sizeof(g_test_frag_spv_data));
+ return 0;
+}
diff --git a/tests/projects/other/glsl2spv/src/test.frag b/tests/projects/other/glsl2spv/src/test.frag
new file mode 100644
index 000000000..9aeec4257
--- /dev/null
+++ b/tests/projects/other/glsl2spv/src/test.frag
@@ -0,0 +1,6 @@
+#version 330
+precision mediump float;
+
+void main() {
+}
+
diff --git a/tests/projects/other/glsl2spv/src/test.vert b/tests/projects/other/glsl2spv/src/test.vert
new file mode 100644
index 000000000..31dedf3e7
--- /dev/null
+++ b/tests/projects/other/glsl2spv/src/test.vert
@@ -0,0 +1,5 @@
+#version 330
+precision mediump float;
+
+void main() {
+}
diff --git a/tests/projects/other/glsl2spv/xmake.lua b/tests/projects/other/glsl2spv/xmake.lua
new file mode 100644
index 000000000..111927e56
--- /dev/null
+++ b/tests/projects/other/glsl2spv/xmake.lua
@@ -0,0 +1,11 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("glslang", {configs = {binaryonly = true}})
+
+target("test")
+ set_kind("binary")
+ add_rules("utils.glsl2spv", {bin2c = true})
+ add_files("src/*.c")
+ add_files("src/*.vert", "src/*.frag")
+ add_packages("glslang")
+
diff --git a/tests/projects/other/merge_archive2/src/add.c b/tests/projects/other/merge_archive2/src/add.c
new file mode 100644
index 000000000..be1e084fc
--- /dev/null
+++ b/tests/projects/other/merge_archive2/src/add.c
@@ -0,0 +1,4 @@
+int add(int a, int b)
+{
+ return a + b;
+}
diff --git a/tests/projects/other/merge_archive2/src/main.c b/tests/projects/other/merge_archive2/src/main.c
new file mode 100644
index 000000000..927c9173e
--- /dev/null
+++ b/tests/projects/other/merge_archive2/src/main.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int add(int a, int b);
+int sub(int a, int b);
+int mul(int a, int b);
+int subdir_add(int a, int b);
+int subdir_sub(int a, int b);
+
+int main(int argc, char** argv)
+{
+ printf("%d\n", add(1, 1));
+ printf("%d\n", sub(1, 1));
+ printf("%d\n", mul(1, 1));
+ printf("%d\n", subdir_add(1, 1));
+ printf("%d\n", subdir_sub(1, 1));
+ return 0;
+}
diff --git a/tests/projects/other/merge_archive2/src/mul.c b/tests/projects/other/merge_archive2/src/mul.c
new file mode 100644
index 000000000..c4292f9aa
--- /dev/null
+++ b/tests/projects/other/merge_archive2/src/mul.c
@@ -0,0 +1,4 @@
+int mul(int a, int b)
+{
+ return a * b;
+}
diff --git a/tests/projects/other/merge_archive2/src/sub.c b/tests/projects/other/merge_archive2/src/sub.c
new file mode 100644
index 000000000..b151ec4bc
--- /dev/null
+++ b/tests/projects/other/merge_archive2/src/sub.c
@@ -0,0 +1,4 @@
+int sub(int a, int b)
+{
+ return a - b;
+}
diff --git a/tests/projects/other/merge_archive2/src/subdir/add.c b/tests/projects/other/merge_archive2/src/subdir/add.c
new file mode 100644
index 000000000..318ed98f8
--- /dev/null
+++ b/tests/projects/other/merge_archive2/src/subdir/add.c
@@ -0,0 +1,4 @@
+int subdir_add(int a, int b)
+{
+ return a + b;
+}
diff --git a/tests/projects/other/merge_archive2/src/subdir/sub.c b/tests/projects/other/merge_archive2/src/subdir/sub.c
new file mode 100644
index 000000000..68c4d13ae
--- /dev/null
+++ b/tests/projects/other/merge_archive2/src/subdir/sub.c
@@ -0,0 +1,4 @@
+int subdir_sub(int a, int b)
+{
+ return a - b;
+}
diff --git a/tests/projects/other/merge_archive2/test.lua b/tests/projects/other/merge_archive2/test.lua
new file mode 100644
index 000000000..b76241be2
--- /dev/null
+++ b/tests/projects/other/merge_archive2/test.lua
@@ -0,0 +1,6 @@
+-- main entry
+function main(t)
+
+ -- build project
+ t:build()
+end
diff --git a/tests/projects/other/merge_archive2/xmake.lua b/tests/projects/other/merge_archive2/xmake.lua
new file mode 100644
index 000000000..be1f45de0
--- /dev/null
+++ b/tests/projects/other/merge_archive2/xmake.lua
@@ -0,0 +1,21 @@
+add_rules("mode.debug", "mode.release")
+
+target("add")
+ set_kind("static")
+ add_files("src/add.c")
+ add_files("src/subdir/add.c")
+
+target("sub")
+ set_kind("static")
+ add_files("src/sub.c")
+ add_files("src/subdir/sub.c")
+
+target("mul")
+ set_kind("static")
+ add_deps("add", "sub")
+ add_files("src/mul.c")
+ set_policy("build.merge_archive", true)
+
+target("test")
+ add_deps("mul")
+ add_files("src/main.c")
diff --git a/tests/projects/other/multiplats_vs/xmake.lua b/tests/projects/other/multiplats_vs/xmake.lua
index 4e61a20a1..255e2e913 100644
--- a/tests/projects/other/multiplats_vs/xmake.lua
+++ b/tests/projects/other/multiplats_vs/xmake.lua
@@ -1,7 +1,7 @@
add_rules("mode.debug", "mode.release")
rule("vs2015_x86")
- before_load(function (target)
+ on_load(function (target)
target:set("arch", "x86")
target:set("toolchains", "msvc", {vs = "2015"})
end)
diff --git a/tests/projects/package/brew/.gitignore b/tests/projects/package/brew/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/package/brew/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/package/brew/src/main.cpp b/tests/projects/package/brew/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/projects/package/brew/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/projects/package/brew/xmake.lua b/tests/projects/package/brew/xmake.lua
new file mode 100644
index 000000000..214f5e5e0
--- /dev/null
+++ b/tests/projects/package/brew/xmake.lua
@@ -0,0 +1,78 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("brew::pcre2/libpcre2-8", {alias = "pcre2"})
+
+target("brew")
+ set_kind("binary")
+ add_files("src/*.cpp")
+ add_packages("pcre2")
+
+--
+-- If you want to known more usage about xmake, please see https://xmake.io
+--
+-- ## FAQ
+--
+-- You can enter the project directory firstly before building project.
+--
+-- $ cd projectdir
+--
+-- 1. How to build project?
+--
+-- $ xmake
+--
+-- 2. How to configure project?
+--
+-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
+--
+-- 3. Where is the build output directory?
+--
+-- The default output directory is `./build` and you can configure the output directory.
+--
+-- $ xmake f -o outputdir
+-- $ xmake
+--
+-- 4. How to run and debug target after building project?
+--
+-- $ xmake run [targetname]
+-- $ xmake run -d [targetname]
+--
+-- 5. How to install target to the system directory or other output directory?
+--
+-- $ xmake install
+-- $ xmake install -o installdir
+--
+-- 6. Add some frequently-used compilation flags in xmake.lua
+--
+-- @code
+-- -- add debug and release modes
+-- add_rules("mode.debug", "mode.release")
+--
+-- -- add macro defination
+-- add_defines("NDEBUG", "_GNU_SOURCE=1")
+--
+-- -- set warning all as error
+-- set_warnings("all", "error")
+--
+-- -- set language: c99, c++11
+-- set_languages("c99", "c++11")
+--
+-- -- set optimization: none, faster, fastest, smallest
+-- set_optimize("fastest")
+--
+-- -- add include search directories
+-- add_includedirs("/usr/include", "/usr/local/include")
+--
+-- -- add link libraries and search directories
+-- add_links("tbox")
+-- add_linkdirs("/usr/local/lib", "/usr/lib")
+--
+-- -- add system link libraries
+-- add_syslinks("z", "pthread")
+--
+-- -- add compilation and link flags
+-- add_cxflags("-stdnolib", "-fno-strict-aliasing")
+-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
+--
+-- @endcode
+--
+
diff --git a/tests/projects/package/cmake/.gitignore b/tests/projects/package/cmake/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/package/cmake/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/package/cmake/src/main.cpp b/tests/projects/package/cmake/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/projects/package/cmake/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/projects/package/cmake/xmake.lua b/tests/projects/package/cmake/xmake.lua
new file mode 100644
index 000000000..b6490032d
--- /dev/null
+++ b/tests/projects/package/cmake/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("cmake::ZLIB", {system = true})
+add_requires("cmake::LibXml2", {system = true})
+add_requires("cmake::Boost", {system = true,
+ configs = {components = {"regex", "system"}, presets = {Boost_USE_STATIC_LIB = true}}})
+target("test")
+ set_kind("binary")
+ add_files("src/*.cpp")
+ add_packages("cmake::ZLIB", "cmake::Boost", "cmake::LibXml2")
+
+
diff --git a/tests/projects/package/conan/.gitignore b/tests/projects/package/conan/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/package/conan/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/package/conan/src/main.cpp b/tests/projects/package/conan/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/projects/package/conan/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/projects/package/conan/xmake.lua b/tests/projects/package/conan/xmake.lua
new file mode 100644
index 000000000..69f7d2052
--- /dev/null
+++ b/tests/projects/package/conan/xmake.lua
@@ -0,0 +1,9 @@
+add_requires("conan::zlib/1.2.11", {alias = "zlib", debug = true})
+add_requires("conan::openssl/1.1.1g", {alias = "openssl",
+ configs = {options = "OpenSSL:shared=True"}})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.cpp")
+ add_packages("openssl", "zlib")
+
diff --git a/tests/projects/package/multiconfig/xmake-requires.lock b/tests/projects/package/multiconfig/xmake-requires.lock
new file mode 100644
index 000000000..359015a18
--- /dev/null
+++ b/tests/projects/package/multiconfig/xmake-requires.lock
@@ -0,0 +1,31 @@
+{
+ __meta__ = {
+ version = "1.0"
+ },
+ ["macosx|x86_64"] = {
+ ["zlib#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.2.11"
+ },
+ ["zlib~debug#55833b12"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.2.11"
+ },
+ ["zlib~shared#b6ab42cb"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.2.11"
+ }
+ }
+}
diff --git a/tests/projects/package/multiconfig/xmake.lua b/tests/projects/package/multiconfig/xmake.lua
index 09121e8d2..7aa2bdffb 100644
--- a/tests/projects/package/multiconfig/xmake.lua
+++ b/tests/projects/package/multiconfig/xmake.lua
@@ -2,6 +2,7 @@ add_requires("zlib", {system = false})
add_requires("zlib", {system = false}) -- test repeat requires
add_requires("zlib~debug", {system = false, debug = true})
add_requires("zlib~shared", {system = false, configs = {shared = true}, alias = "zlib_shared"})
+set_policy("package.requires_lock", true)
target("test1")
set_kind("binary")
diff --git a/tests/projects/package/toolchain_muslcc/xmake-requires.lock b/tests/projects/package/toolchain_muslcc/xmake-requires.lock
new file mode 100644
index 000000000..05f143646
--- /dev/null
+++ b/tests/projects/package/toolchain_muslcc/xmake-requires.lock
@@ -0,0 +1,145 @@
+{
+ __meta__ = {
+ version = "1.0"
+ },
+ ["macosx|x86_64"] = {
+ ["autoconf#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "4498f11267de5112199152ab030ed139c985ad5a",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "2.71"
+ },
+ ["automake#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.16.4"
+ },
+ ["cmake#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "4498f11267de5112199152ab030ed139c985ad5a",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "3.21.0"
+ },
+ ["gmp#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "89ac4c1e2d360bc3a8c3f4cdedf4ee683701de74",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "6.2.1"
+ },
+ ["libisl 0.22#67114504"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "0.22"
+ },
+ ["libogg#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "v1.3.4"
+ },
+ ["libplist#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "2.2.0"
+ },
+ ["libtool#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "2.4.6"
+ },
+ ["m4#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "89ac4c1e2d360bc3a8c3f4cdedf4ee683701de74",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.4.19"
+ },
+ ["muslcc#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "20210202"
+ },
+ ["pkg-config#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "89ac4c1e2d360bc3a8c3f4cdedf4ee683701de74",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "0.29.2"
+ },
+ ["zlib#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.2.11"
+ }
+ },
+ ["windows|x64"] = {
+ ["cmake#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "8e8c5e4d1c7e8b047b23333594d23b4b85163aed",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "3.21.0"
+ },
+ ["libogg#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "2b1cb74b289ae3221241985db4401a495c42fde3",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "v1.3.4"
+ },
+ ["make#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "2b1cb74b289ae3221241985db4401a495c42fde3",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "4.3"
+ },
+ ["muslcc#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "2b1cb74b289ae3221241985db4401a495c42fde3",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "20210202"
+ },
+ ["zlib#31fecfc4"] = {
+ repo = {
+ branch = "master",
+ commit = "2b1cb74b289ae3221241985db4401a495c42fde3",
+ url = "https://github.com/xmake-io/xmake-repo.git"
+ },
+ version = "1.2.11"
+ }
+ }
+}
diff --git a/tests/projects/package/toolchain_muslcc/xmake.lua b/tests/projects/package/toolchain_muslcc/xmake.lua
index bf5e98e8c..b111d5976 100644
--- a/tests/projects/package/toolchain_muslcc/xmake.lua
+++ b/tests/projects/package/toolchain_muslcc/xmake.lua
@@ -4,6 +4,9 @@ add_rules("mode.debug", "mode.release")
set_plat("cross")
set_arch("arm")
+-- lock requires
+set_policy("package.requires_lock", true)
+
-- add library packages
-- for testing zlib/xmake, libplist/autoconf, libogg/cmake
add_requires("zlib", "libogg", {system = false})
diff --git a/tests/projects/package/vcpkg/.gitignore b/tests/projects/package/vcpkg/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/package/vcpkg/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/package/vcpkg/src/main.cpp b/tests/projects/package/vcpkg/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/projects/package/vcpkg/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/projects/package/vcpkg/xmake.lua b/tests/projects/package/vcpkg/xmake.lua
new file mode 100644
index 000000000..3f5dbcf55
--- /dev/null
+++ b/tests/projects/package/vcpkg/xmake.lua
@@ -0,0 +1,8 @@
+add_requires("vcpkg::zlib", "vcpkg::pcre2")
+add_requires("vcpkg::boost[core]", {alias = "boost"})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.cpp")
+ add_packages("vcpkg::zlib", "vcpkg::pcre2", "boost")
+
diff --git a/tests/projects/package/vcpkg_manifest/.gitignore b/tests/projects/package/vcpkg_manifest/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/projects/package/vcpkg_manifest/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/projects/package/vcpkg_manifest/src/main.cpp b/tests/projects/package/vcpkg_manifest/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/projects/package/vcpkg_manifest/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/projects/package/vcpkg_manifest/xmake.lua b/tests/projects/package/vcpkg_manifest/xmake.lua
new file mode 100644
index 000000000..8a851328b
--- /dev/null
+++ b/tests/projects/package/vcpkg_manifest/xmake.lua
@@ -0,0 +1,9 @@
+add_requires("vcpkg::zlib 1.2.11+10")
+add_requires("vcpkg::fmt >=8.0.1", {configs = {baseline = "50fd3d9957195575849a49fa591e645f1d8e7156"}})
+add_requires("vcpkg::libpng", {configs = {features = {"apng"}}})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.cpp")
+ add_packages("vcpkg::zlib", "vcpkg::fmt", "vcpkg::libpng")
+
diff --git a/tests/projects/pascal/console/src/main.pas b/tests/projects/pascal/console/src/main.pas
new file mode 100644
index 000000000..a908ffab7
--- /dev/null
+++ b/tests/projects/pascal/console/src/main.pas
@@ -0,0 +1,4 @@
+program Hello;
+begin
+ writeln ('Hello, world.');
+end.
diff --git a/tests/projects/pascal/console/xmake.lua b/tests/projects/pascal/console/xmake.lua
new file mode 100644
index 000000000..32fd531a2
--- /dev/null
+++ b/tests/projects/pascal/console/xmake.lua
@@ -0,0 +1,5 @@
+add_rules("mode.debug", "mode.release")
+target("test")
+ set_kind("binary")
+ add_files("src/*.pas")
+
diff --git a/tests/projects/pascal/console_with_c/src/foo.c b/tests/projects/pascal/console_with_c/src/foo.c
new file mode 100644
index 000000000..66ca7cfb4
--- /dev/null
+++ b/tests/projects/pascal/console_with_c/src/foo.c
@@ -0,0 +1,7 @@
+#include <stdint.h>
+
+extern int64_t fib(int64_t n)
+{
+ return n > 1 ? fib(n - 1) + fib(n - 2) : 1;
+}
+
diff --git a/tests/projects/pascal/console_with_c/src/main.pas b/tests/projects/pascal/console_with_c/src/main.pas
new file mode 100644
index 000000000..ce34e4af9
--- /dev/null
+++ b/tests/projects/pascal/console_with_c/src/main.pas
@@ -0,0 +1,12 @@
+program hello;
+
+function fib(n: Int64): Int64;
+ cdecl; external 'foo';
+
+var
+ Value: Integer;
+begin
+ Value := 5;
+ WriteLn(fib(Value));
+end.
+
diff --git a/tests/projects/pascal/console_with_c/xmake.lua b/tests/projects/pascal/console_with_c/xmake.lua
new file mode 100644
index 000000000..111efc0c9
--- /dev/null
+++ b/tests/projects/pascal/console_with_c/xmake.lua
@@ -0,0 +1,9 @@
+add_rules("mode.debug", "mode.release")
+target("foo")
+ set_kind("static")
+ add_files("src/foo.c")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.pas")
diff --git a/tests/projects/pascal/shared/src/foo.pas b/tests/projects/pascal/shared/src/foo.pas
new file mode 100644
index 000000000..788950f46
--- /dev/null
+++ b/tests/projects/pascal/shared/src/foo.pas
@@ -0,0 +1,19 @@
+library foo;
+
+{$mode objfpc}{$H+}
+
+function fib(n : Int64) : Int64; cdecl;
+begin
+ if n > 1 then
+ begin
+ Result := fib(n - 1) + fib(n - 2);
+ end
+ else
+ Result := 1;
+end;
+
+exports
+ fib;
+end.
+
+
diff --git a/tests/projects/pascal/shared/src/main.pas b/tests/projects/pascal/shared/src/main.pas
new file mode 100644
index 000000000..02d5e88d0
--- /dev/null
+++ b/tests/projects/pascal/shared/src/main.pas
@@ -0,0 +1,13 @@
+program hello;
+
+function fib(n: Int64): Int64;
+ cdecl; external 'foo';
+
+var
+ Value: Integer;
+begin
+ Value := 5;
+ WriteLn(fib(Value));
+end.
+
+
diff --git a/tests/projects/pascal/shared/xmake.lua b/tests/projects/pascal/shared/xmake.lua
new file mode 100644
index 000000000..d96c29d5f
--- /dev/null
+++ b/tests/projects/pascal/shared/xmake.lua
@@ -0,0 +1,9 @@
+add_rules("mode.debug", "mode.release")
+target("foo")
+ set_kind("shared")
+ add_files("src/foo.pas")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.pas")
diff --git a/tests/projects/pybind/example/src/example.cpp b/tests/projects/pybind/example/src/example.cpp
new file mode 100644
index 000000000..cb1bad194
--- /dev/null
+++ b/tests/projects/pybind/example/src/example.cpp
@@ -0,0 +1,38 @@
+#include <pybind11/pybind11.h>
+
+#define STRINGIFY(x) #x
+#define MACRO_STRINGIFY(x) STRINGIFY(x)
+
+int add(int i, int j) {
+ return i + j;
+}
+
+namespace py = pybind11;
+
+PYBIND11_MODULE(example, m) {
+ m.doc() = R"pbdoc(
+ Pybind11 example plugin
+ -----------------------
+ .. currentmodule:: example
+ .. autosummary::
+ :toctree: _generate
+ add
+ subtract
+ )pbdoc";
+
+ m.def("add", &add, R"pbdoc(
+ Add two numbers
+ Some other explanation about the add function.
+ )pbdoc");
+
+ m.def("subtract", [](int i, int j) { return i - j; }, R"pbdoc(
+ Subtract two numbers
+ Some other explanation about the subtract function.
+ )pbdoc");
+
+#ifdef VERSION_INFO
+ m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);
+#else
+ m.attr("__version__") = "dev";
+#endif
+}
diff --git a/tests/projects/pybind/example/xmake.lua b/tests/projects/pybind/example/xmake.lua
new file mode 100644
index 000000000..19b7b5a9e
--- /dev/null
+++ b/tests/projects/pybind/example/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("pybind11")
+
+target("example")
+ add_rules("python.library")
+ add_files("src/*.cpp")
+ add_packages("pybind11")
+ set_languages("c++11")
diff --git a/tests/projects/pybind/example_with_soabi/src/example.cpp b/tests/projects/pybind/example_with_soabi/src/example.cpp
new file mode 100644
index 000000000..cb1bad194
--- /dev/null
+++ b/tests/projects/pybind/example_with_soabi/src/example.cpp
@@ -0,0 +1,38 @@
+#include <pybind11/pybind11.h>
+
+#define STRINGIFY(x) #x
+#define MACRO_STRINGIFY(x) STRINGIFY(x)
+
+int add(int i, int j) {
+ return i + j;
+}
+
+namespace py = pybind11;
+
+PYBIND11_MODULE(example, m) {
+ m.doc() = R"pbdoc(
+ Pybind11 example plugin
+ -----------------------
+ .. currentmodule:: example
+ .. autosummary::
+ :toctree: _generate
+ add
+ subtract
+ )pbdoc";
+
+ m.def("add", &add, R"pbdoc(
+ Add two numbers
+ Some other explanation about the add function.
+ )pbdoc");
+
+ m.def("subtract", [](int i, int j) { return i - j; }, R"pbdoc(
+ Subtract two numbers
+ Some other explanation about the subtract function.
+ )pbdoc");
+
+#ifdef VERSION_INFO
+ m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);
+#else
+ m.attr("__version__") = "dev";
+#endif
+}
diff --git a/tests/projects/pybind/example_with_soabi/xmake.lua b/tests/projects/pybind/example_with_soabi/xmake.lua
new file mode 100644
index 000000000..12d8ad334
--- /dev/null
+++ b/tests/projects/pybind/example_with_soabi/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("pybind11")
+
+target("example")
+ add_rules("python.library", {soabi = true})
+ add_files("src/*.cpp")
+ add_packages("pybind11")
+ set_languages("c++11")
diff --git a/tests/projects/rust/cargo_deps/src/main.rs b/tests/projects/rust/cargo_deps/src/main.rs
new file mode 100644
index 000000000..f1ec987bf
--- /dev/null
+++ b/tests/projects/rust/cargo_deps/src/main.rs
@@ -0,0 +1,12 @@
+extern crate base64;
+
+use base64::{encode, decode};
+
+fn main() {
+ let a = b"hello world";
+ let b = "aGVsbG8gd29ybGQ=";
+
+ assert_eq!(encode(a), b);
+ assert_eq!(a, &decode(b).unwrap()[..]);
+ println!("{}", encode(a));
+}
diff --git a/tests/projects/rust/cargo_deps/xmake.lua b/tests/projects/rust/cargo_deps/xmake.lua
new file mode 100644
index 000000000..73340dedf
--- /dev/null
+++ b/tests/projects/rust/cargo_deps/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("cargo::base64 0.13.0")
+add_requires("cargo::flate2 1.0.17", {configs = {features = "zlib"}})
+
+target("test")
+ set_kind("binary")
+ add_files("src/main.rs")
+ add_packages("cargo::base64", "cargo::flate2")
diff --git a/tests/projects/rust/console/src/main.rs b/tests/projects/rust/console/src/main.rs
index e8d2ae9b2..88d5e2749 100644
--- a/tests/projects/rust/console/src/main.rs
+++ b/tests/projects/rust/console/src/main.rs
@@ -1,4 +1,3 @@
-fn main()
-{
+fn main() {
println!("hello xmake!");
}
diff --git a/tests/projects/rust/console/xmake.lua b/tests/projects/rust/console/xmake.lua
index 2a5d3e012..d561403ac 100644
--- a/tests/projects/rust/console/xmake.lua
+++ b/tests/projects/rust/console/xmake.lua
@@ -2,5 +2,5 @@ add_rules("mode.debug", "mode.release")
target("test")
set_kind("binary")
- add_files("src/*.rs")
+ add_files("src/main.rs")
diff --git a/tests/projects/rust/cxx_call_rust_library/src/bridge.rsx b/tests/projects/rust/cxx_call_rust_library/src/bridge.rsx
new file mode 100644
index 000000000..3710f4bfd
--- /dev/null
+++ b/tests/projects/rust/cxx_call_rust_library/src/bridge.rsx
@@ -0,0 +1,6 @@
+#[cxx::bridge]
+mod foo {
+ extern "Rust" {
+ fn add(a: i32, b: i32) -> i32;
+ }
+}
diff --git a/tests/projects/rust/cxx_call_rust_library/src/foo.rs b/tests/projects/rust/cxx_call_rust_library/src/foo.rs
new file mode 100644
index 000000000..f78bfa99d
--- /dev/null
+++ b/tests/projects/rust/cxx_call_rust_library/src/foo.rs
@@ -0,0 +1,12 @@
+#[cxx::bridge]
+mod foo {
+ extern "Rust" {
+ fn add(a: i32, b: i32) -> i32;
+ }
+}
+
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
+
diff --git a/tests/projects/rust/cxx_call_rust_library/src/main.cc b/tests/projects/rust/cxx_call_rust_library/src/main.cc
new file mode 100644
index 000000000..d79b319f9
--- /dev/null
+++ b/tests/projects/rust/cxx_call_rust_library/src/main.cc
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "bridge.rs.h"
+
+int main(int argc, char** argv) {
+ printf("add(1, 2) == %d\n", add(1, 2));
+ return 0;
+}
diff --git a/tests/projects/rust/cxx_call_rust_library/xmake.lua b/tests/projects/rust/cxx_call_rust_library/xmake.lua
new file mode 100644
index 000000000..30d54cc02
--- /dev/null
+++ b/tests/projects/rust/cxx_call_rust_library/xmake.lua
@@ -0,0 +1,16 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("cargo::cxx 1.0")
+
+target("foo")
+ set_kind("static")
+ add_files("src/foo.rs")
+ set_values("rust.cratetype", "staticlib")
+ add_packages("cargo::cxx")
+
+target("test")
+ set_kind("binary")
+ add_rules("rust.cxxbridge")
+ add_deps("foo")
+ add_files("src/main.cc")
+ add_files("src/bridge.rsx")
diff --git a/tests/projects/rust/rust_call_cxx_library/src/foo.cc b/tests/projects/rust/rust_call_cxx_library/src/foo.cc
new file mode 100644
index 000000000..bb2eb9292
--- /dev/null
+++ b/tests/projects/rust/rust_call_cxx_library/src/foo.cc
@@ -0,0 +1,3 @@
+extern "C" int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/projects/rust/rust_call_cxx_library/src/main.rs b/tests/projects/rust/rust_call_cxx_library/src/main.rs
new file mode 100644
index 000000000..1eac379d2
--- /dev/null
+++ b/tests/projects/rust/rust_call_cxx_library/src/main.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn add(a: i32, b: i32) -> i32;
+}
+
+fn main() {
+ unsafe {
+ println!("add(1, 2) = {}", add(1, 2));
+ }
+}
diff --git a/tests/projects/rust/rust_call_cxx_library/test.lua b/tests/projects/rust/rust_call_cxx_library/test.lua
new file mode 100644
index 000000000..92168a8c1
--- /dev/null
+++ b/tests/projects/rust/rust_call_cxx_library/test.lua
@@ -0,0 +1,10 @@
+-- main entry
+function main(t)
+
+ -- build project
+ if is_host("macosx") and os.arch() ~= "arm64" then
+ t:build()
+ else
+ return t:skip("wrong host platform")
+ end
+end
diff --git a/tests/projects/rust/rust_call_cxx_library/xmake.lua b/tests/projects/rust/rust_call_cxx_library/xmake.lua
new file mode 100644
index 000000000..e150aca4a
--- /dev/null
+++ b/tests/projects/rust/rust_call_cxx_library/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+
+target("foo")
+ set_kind("static")
+ add_files("src/foo.cc")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.rs")
+
+
diff --git a/tests/projects/rust/shared_library/src/foo.rs b/tests/projects/rust/shared_library/src/foo.rs
new file mode 100644
index 000000000..a3a3aa4a6
--- /dev/null
+++ b/tests/projects/rust/shared_library/src/foo.rs
@@ -0,0 +1,4 @@
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
diff --git a/tests/projects/rust/shared_library/src/main.rs b/tests/projects/rust/shared_library/src/main.rs
new file mode 100644
index 000000000..205d23da3
--- /dev/null
+++ b/tests/projects/rust/shared_library/src/main.rs
@@ -0,0 +1,6 @@
+extern crate foo;
+
+fn main() {
+ println!("hello xmake!");
+ println!("add: {}", foo::add(1, 1));
+}
diff --git a/tests/projects/rust/shared_library/xmake.lua b/tests/projects/rust/shared_library/xmake.lua
new file mode 100644
index 000000000..edacfe4d6
--- /dev/null
+++ b/tests/projects/rust/shared_library/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+
+target("foo")
+ set_kind("shared")
+ add_files("src/foo.rs")
+
+target("test")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.rs")
+
+
diff --git a/tests/projects/rust/static_library/src/foo.rs b/tests/projects/rust/static_library/src/foo.rs
new file mode 100644
index 000000000..a3a3aa4a6
--- /dev/null
+++ b/tests/projects/rust/static_library/src/foo.rs
@@ -0,0 +1,4 @@
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
diff --git a/tests/projects/rust/static_library/src/interfaces.rs b/tests/projects/rust/static_library/src/interfaces.rs
deleted file mode 100644
index 277008ba4..000000000
--- a/tests/projects/rust/static_library/src/interfaces.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub fn add(a: i32, b: i32) -> i32
-{
- return a + b;
-}
-
diff --git a/tests/projects/rust/static_library/src/main.rs b/tests/projects/rust/static_library/src/main.rs
index 0cd4449d1..de8604a65 100644
--- a/tests/projects/rust/static_library/src/main.rs
+++ b/tests/projects/rust/static_library/src/main.rs
@@ -1,7 +1,5 @@
-extern crate interfaces;
-
-fn main()
-{
+extern crate foo;
+fn main() {
println!("hello xmake!");
- println!("add: {}", interfaces::add(1, 1));
+ println!("add: {}", foo::add(1, 1));
}
diff --git a/tests/projects/rust/static_library/xmake.lua b/tests/projects/rust/static_library/xmake.lua
index fa38d17e5..c50e50874 100644
--- a/tests/projects/rust/static_library/xmake.lua
+++ b/tests/projects/rust/static_library/xmake.lua
@@ -1,12 +1,12 @@
add_rules("mode.debug", "mode.release")
-target("interfaces")
+target("foo")
set_kind("static")
- add_files("src/interfaces.rs")
+ add_files("src/foo.rs")
target("test")
set_kind("binary")
- add_deps("interfaces")
+ add_deps("foo")
add_files("src/main.rs")
diff --git a/tests/projects/swig/lua_c/src/example.c b/tests/projects/swig/lua_c/src/example.c
new file mode 100644
index 000000000..06f76c542
--- /dev/null
+++ b/tests/projects/swig/lua_c/src/example.c
@@ -0,0 +1,4 @@
+int fact(int n) {
+ return n;
+}
+
diff --git a/tests/projects/swig/lua_c/src/example.i b/tests/projects/swig/lua_c/src/example.i
new file mode 100644
index 000000000..e952f6123
--- /dev/null
+++ b/tests/projects/swig/lua_c/src/example.i
@@ -0,0 +1,5 @@
+%module example
+%{
+extern int fact(int n);
+%}
+extern int fact(int n);
diff --git a/tests/projects/swig/lua_c/xmake.lua b/tests/projects/swig/lua_c/xmake.lua
new file mode 100644
index 000000000..06dfac12b
--- /dev/null
+++ b/tests/projects/swig/lua_c/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("lua")
+
+target("example")
+ add_rules("swig.c", {moduletype = "lua"})
+ add_files("src/example.i", {swigflags = "-no-old-metatable-bindings"})
+ add_files("src/example.c")
+ add_packages("lua")
diff --git a/tests/projects/swig/python_c/src/example.c b/tests/projects/swig/python_c/src/example.c
new file mode 100644
index 000000000..b0ddc9c26
--- /dev/null
+++ b/tests/projects/swig/python_c/src/example.c
@@ -0,0 +1,14 @@
+double My_variable = 3.0;
+
+/* Compute factorial of n */
+int fact(int n) {
+ if (n <= 1)
+ return 1;
+ else
+ return n*fact(n-1);
+}
+
+/* Compute n mod m */
+int my_mod(int n, int m) {
+ return(n % m);
+}
diff --git a/tests/projects/swig/python_c/src/example.i b/tests/projects/swig/python_c/src/example.i
new file mode 100644
index 000000000..34193edc7
--- /dev/null
+++ b/tests/projects/swig/python_c/src/example.i
@@ -0,0 +1,11 @@
+%module example
+%{
+/* Put headers and other declarations here */
+extern double My_variable;
+extern int fact(int);
+extern int my_mod(int n, int m);
+%}
+
+extern double My_variable;
+extern int fact(int);
+extern int my_mod(int n, int m);
diff --git a/tests/projects/swig/python_c/xmake.lua b/tests/projects/swig/python_c/xmake.lua
new file mode 100644
index 000000000..7cc23e42b
--- /dev/null
+++ b/tests/projects/swig/python_c/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("python 3.x")
+
+target("example")
+ add_rules("swig.c", {moduletype = "python"})
+ add_files("src/example.i", {scriptdir = "share"})
+ add_files("src/example.c")
+ add_packages("python")
diff --git a/tests/projects/swig/python_c_with_soabi/src/example.c b/tests/projects/swig/python_c_with_soabi/src/example.c
new file mode 100644
index 000000000..b0ddc9c26
--- /dev/null
+++ b/tests/projects/swig/python_c_with_soabi/src/example.c
@@ -0,0 +1,14 @@
+double My_variable = 3.0;
+
+/* Compute factorial of n */
+int fact(int n) {
+ if (n <= 1)
+ return 1;
+ else
+ return n*fact(n-1);
+}
+
+/* Compute n mod m */
+int my_mod(int n, int m) {
+ return(n % m);
+}
diff --git a/tests/projects/swig/python_c_with_soabi/src/example.i b/tests/projects/swig/python_c_with_soabi/src/example.i
new file mode 100644
index 000000000..34193edc7
--- /dev/null
+++ b/tests/projects/swig/python_c_with_soabi/src/example.i
@@ -0,0 +1,11 @@
+%module example
+%{
+/* Put headers and other declarations here */
+extern double My_variable;
+extern int fact(int);
+extern int my_mod(int n, int m);
+%}
+
+extern double My_variable;
+extern int fact(int);
+extern int my_mod(int n, int m);
diff --git a/tests/projects/swig/python_c_with_soabi/xmake.lua b/tests/projects/swig/python_c_with_soabi/xmake.lua
new file mode 100644
index 000000000..81dd49926
--- /dev/null
+++ b/tests/projects/swig/python_c_with_soabi/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("python 3.x")
+
+target("example")
+ add_rules("swig.c", {moduletype = "python", soabi = true})
+ add_files("src/example.i", {scriptdir = "share"})
+ add_files("src/example.c")
+ add_packages("python")
diff --git a/tests/projects/swig/python_cpp/src/example.cpp b/tests/projects/swig/python_cpp/src/example.cpp
new file mode 100644
index 000000000..b0ddc9c26
--- /dev/null
+++ b/tests/projects/swig/python_cpp/src/example.cpp
@@ -0,0 +1,14 @@
+double My_variable = 3.0;
+
+/* Compute factorial of n */
+int fact(int n) {
+ if (n <= 1)
+ return 1;
+ else
+ return n*fact(n-1);
+}
+
+/* Compute n mod m */
+int my_mod(int n, int m) {
+ return(n % m);
+}
diff --git a/tests/projects/swig/python_cpp/src/example.i b/tests/projects/swig/python_cpp/src/example.i
new file mode 100644
index 000000000..34193edc7
--- /dev/null
+++ b/tests/projects/swig/python_cpp/src/example.i
@@ -0,0 +1,11 @@
+%module example
+%{
+/* Put headers and other declarations here */
+extern double My_variable;
+extern int fact(int);
+extern int my_mod(int n, int m);
+%}
+
+extern double My_variable;
+extern int fact(int);
+extern int my_mod(int n, int m);
diff --git a/tests/projects/swig/python_cpp/xmake.lua b/tests/projects/swig/python_cpp/xmake.lua
new file mode 100644
index 000000000..1aa612211
--- /dev/null
+++ b/tests/projects/swig/python_cpp/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.release", "mode.debug")
+add_requires("python 3.x")
+
+target("example")
+ add_rules("swig.cpp", {moduletype = "python"})
+ add_files("src/example.i", {scriptdir = "share"})
+ add_files("src/example.cpp")
+ add_packages("python")
diff --git a/tests/projects/vala/gtk+3/src/main.vala b/tests/projects/vala/gtk+3/src/main.vala
new file mode 100644
index 000000000..7f253a9fe
--- /dev/null
+++ b/tests/projects/vala/gtk+3/src/main.vala
@@ -0,0 +1,24 @@
+using Gtk;
+
+int main (string[] args) {
+ Gtk.init (ref args);
+
+ var window = new Window ();
+ window.title = "First GTK+ Program";
+ window.border_width = 10;
+ window.window_position = WindowPosition.CENTER;
+ window.set_default_size (350, 70);
+ window.destroy.connect (Gtk.main_quit);
+
+ var button = new Button.with_label ("Click me!");
+ button.clicked.connect (() => {
+ button.label = "Thank you";
+ });
+
+ window.add (button);
+ window.show_all ();
+
+ Gtk.main ();
+ return 0;
+}
+
diff --git a/tests/projects/vala/gtk+3/xmake.lua b/tests/projects/vala/gtk+3/xmake.lua
new file mode 100644
index 000000000..5e9f2b8da
--- /dev/null
+++ b/tests/projects/vala/gtk+3/xmake.lua
@@ -0,0 +1,10 @@
+add_rules("mode.release", "mode.debug")
+
+add_requires("gtk+3", "glib")
+
+target("test")
+ set_kind("binary")
+ add_rules("vala")
+ add_files("src/*.vala")
+ add_packages("gtk+3", "glib")
+ add_values("vala.packages", "gtk+-3.0")
diff --git a/tests/projects/vala/sharedlib/src/main.vala b/tests/projects/vala/sharedlib/src/main.vala
new file mode 100644
index 000000000..da9fd895e
--- /dev/null
+++ b/tests/projects/vala/sharedlib/src/main.vala
@@ -0,0 +1,6 @@
+using MyMath;
+
+public void main() {
+ stdout.printf("\n\t2 + 3 is %d", sum(2, 3));
+ stdout.printf("\n\t8 squared is %d\n", square(8));
+}
diff --git a/tests/projects/vala/sharedlib/src/mymath.vala b/tests/projects/vala/sharedlib/src/mymath.vala
new file mode 100644
index 000000000..4f4e761c5
--- /dev/null
+++ b/tests/projects/vala/sharedlib/src/mymath.vala
@@ -0,0 +1,9 @@
+namespace MyMath {
+ public int sum(int a, int b) {
+ return(a + b);
+ }
+
+ public int square(int a) {
+ return(a * a);
+ }
+}
diff --git a/tests/projects/vala/sharedlib/xmake.lua b/tests/projects/vala/sharedlib/xmake.lua
new file mode 100644
index 000000000..10c90c88b
--- /dev/null
+++ b/tests/projects/vala/sharedlib/xmake.lua
@@ -0,0 +1,18 @@
+add_rules("mode.release", "mode.debug")
+
+add_requires("glib")
+
+target("mymath")
+ set_kind("shared")
+ add_rules("vala")
+ add_files("src/mymath.vala")
+ add_values("vala.header", "mymath.h")
+ add_values("vala.vapi", "mymath-1.0.vapi")
+ add_packages("glib")
+
+target("test")
+ set_kind("binary")
+ add_deps("mymath")
+ add_rules("vala")
+ add_files("src/main.vala")
+ add_packages("glib")
diff --git a/tests/projects/vala/sqlite3/src/main.vala b/tests/projects/vala/sqlite3/src/main.vala
new file mode 100644
index 000000000..536e0d5e0
--- /dev/null
+++ b/tests/projects/vala/sqlite3/src/main.vala
@@ -0,0 +1,63 @@
+/**
+ * Using SQLite in Vala Sample Code
+ * Port of an example found on the SQLite site.
+ * http://www.sqlite.org/quickstart.html
+ */
+
+using GLib;
+using Sqlite;
+
+public class SqliteSample : GLib.Object {
+
+ public static int callback (int n_columns, string[] values,
+ string[] column_names)
+ {
+ for (int i = 0; i < n_columns; i++) {
+ stdout.printf ("%s = %s\n", column_names[i], values[i]);
+ }
+ stdout.printf ("\n");
+
+ return 0;
+ }
+
+ public static int main (string[] args) {
+ Database db;
+ int rc;
+
+ if (args.length != 3) {
+ stderr.printf ("Usage: %s DATABASE SQL-STATEMENT\n", args[0]);
+ return 1;
+ }
+
+ if (!FileUtils.test (args[1], FileTest.IS_REGULAR)) {
+ stderr.printf ("Database %s does not exist or is directory\n", args[1]);
+ return 1;
+ }
+
+ rc = Database.open (args[1], out db);
+
+ if (rc != Sqlite.OK) {
+ stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ());
+ return 1;
+ }
+
+ rc = db.exec (args[2], callback, null);
+ /* maybe it is better to use closures, so you can access local variables, eg: */
+ /*rc = db.exec(args[2], (n_columns, values, column_names) => {
+ for (int i = 0; i < n_columns; i++) {
+ stdout.printf ("%s = %s\n", column_names[i], values[i]);
+ }
+ stdout.printf ("\n");
+
+ return 0;
+ }, null);
+ */
+
+ if (rc != Sqlite.OK) {
+ stderr.printf ("SQL error: %d, %s\n", rc, db.errmsg ());
+ return 1;
+ }
+
+ return 0;
+ }
+}
diff --git a/tests/projects/vala/sqlite3/xmake.lua b/tests/projects/vala/sqlite3/xmake.lua
new file mode 100644
index 000000000..f1e21e8ce
--- /dev/null
+++ b/tests/projects/vala/sqlite3/xmake.lua
@@ -0,0 +1,10 @@
+add_rules("mode.release", "mode.debug")
+
+add_requires("sqlite3", "glib")
+
+target("test")
+ set_kind("binary")
+ add_rules("vala")
+ add_files("src/*.vala")
+ add_packages("sqlite3", "glib")
+ add_values("vala.packages", "sqlite3")
diff --git a/tests/projects/vala/staticlib/src/main.vala b/tests/projects/vala/staticlib/src/main.vala
new file mode 100644
index 000000000..da9fd895e
--- /dev/null
+++ b/tests/projects/vala/staticlib/src/main.vala
@@ -0,0 +1,6 @@
+using MyMath;
+
+public void main() {
+ stdout.printf("\n\t2 + 3 is %d", sum(2, 3));
+ stdout.printf("\n\t8 squared is %d\n", square(8));
+}
diff --git a/tests/projects/vala/staticlib/src/mymath.vala b/tests/projects/vala/staticlib/src/mymath.vala
new file mode 100644
index 000000000..4f4e761c5
--- /dev/null
+++ b/tests/projects/vala/staticlib/src/mymath.vala
@@ -0,0 +1,9 @@
+namespace MyMath {
+ public int sum(int a, int b) {
+ return(a + b);
+ }
+
+ public int square(int a) {
+ return(a * a);
+ }
+}
diff --git a/tests/projects/vala/staticlib/xmake.lua b/tests/projects/vala/staticlib/xmake.lua
new file mode 100644
index 000000000..d37f1b974
--- /dev/null
+++ b/tests/projects/vala/staticlib/xmake.lua
@@ -0,0 +1,18 @@
+add_rules("mode.release", "mode.debug")
+
+add_requires("glib")
+
+target("mymath")
+ set_kind("static")
+ add_rules("vala")
+ add_files("src/mymath.vala")
+ add_values("vala.header", "mymath.h")
+ add_values("vala.vapi", "mymath-1.0.vapi")
+ add_packages("glib")
+
+target("test")
+ set_kind("binary")
+ add_deps("mymath")
+ add_rules("vala")
+ add_files("src/main.vala")
+ add_packages("glib")
diff --git a/tests/projects/wdk/kmdf/ioctl/driver/nonpnp.c b/tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.c
index 13f811f35..13f811f35 100644
--- a/tests/projects/wdk/kmdf/ioctl/driver/nonpnp.c
+++ b/tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.c
diff --git a/tests/projects/wdk/kmdf/ioctl/driver/nonpnp.h b/tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.h
index c874e79d2..c874e79d2 100644
--- a/tests/projects/wdk/kmdf/ioctl/driver/nonpnp.h
+++ b/tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.h
diff --git a/tests/projects/wdk/kmdf/ioctl/driver/nonpnp.rc b/tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.rc
index cac68f7b2..cac68f7b2 100644
--- a/tests/projects/wdk/kmdf/ioctl/driver/nonpnp.rc
+++ b/tests/projects/windows/driver/kmdf/ioctl/driver/nonpnp.rc
diff --git a/tests/projects/wdk/kmdf/ioctl/driver/trace.h b/tests/projects/windows/driver/kmdf/ioctl/driver/trace.h
index 089f213f0..089f213f0 100644
--- a/tests/projects/wdk/kmdf/ioctl/driver/trace.h
+++ b/tests/projects/windows/driver/kmdf/ioctl/driver/trace.h
diff --git a/tests/projects/wdk/kmdf/ioctl/exe/install.c b/tests/projects/windows/driver/kmdf/ioctl/exe/install.c
index 53d1f7678..53d1f7678 100644
--- a/tests/projects/wdk/kmdf/ioctl/exe/install.c
+++ b/tests/projects/windows/driver/kmdf/ioctl/exe/install.c
diff --git a/tests/projects/wdk/kmdf/ioctl/exe/nonpnp.inf b/tests/projects/windows/driver/kmdf/ioctl/exe/nonpnp.inf
index b20a58b48..b20a58b48 100644
--- a/tests/projects/wdk/kmdf/ioctl/exe/nonpnp.inf
+++ b/tests/projects/windows/driver/kmdf/ioctl/exe/nonpnp.inf
diff --git a/tests/projects/wdk/kmdf/ioctl/exe/testapp.c b/tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c
index c12f26073..c12f26073 100644
--- a/tests/projects/wdk/kmdf/ioctl/exe/testapp.c
+++ b/tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c
diff --git a/tests/projects/wdk/kmdf/ioctl/localwpp.ini b/tests/projects/windows/driver/kmdf/ioctl/localwpp.ini
index c290070a7..c290070a7 100644
--- a/tests/projects/wdk/kmdf/ioctl/localwpp.ini
+++ b/tests/projects/windows/driver/kmdf/ioctl/localwpp.ini
diff --git a/tests/projects/wdk/kmdf/ioctl/public.h b/tests/projects/windows/driver/kmdf/ioctl/public.h
index 02e24be2e..02e24be2e 100644
--- a/tests/projects/wdk/kmdf/ioctl/public.h
+++ b/tests/projects/windows/driver/kmdf/ioctl/public.h
diff --git a/tests/projects/wdk/kmdf/ioctl/xmake.lua b/tests/projects/windows/driver/kmdf/ioctl/xmake.lua
index 9cbaf0b5f..9cbaf0b5f 100644
--- a/tests/projects/wdk/kmdf/ioctl/xmake.lua
+++ b/tests/projects/windows/driver/kmdf/ioctl/xmake.lua
diff --git a/tests/projects/wdk/kmdf/serial/error.c b/tests/projects/windows/driver/kmdf/serial/error.c
index 904e54b05..904e54b05 100644
--- a/tests/projects/wdk/kmdf/serial/error.c
+++ b/tests/projects/windows/driver/kmdf/serial/error.c
diff --git a/tests/projects/wdk/kmdf/serial/flush.c b/tests/projects/windows/driver/kmdf/serial/flush.c
index 695a60a26..695a60a26 100644
--- a/tests/projects/wdk/kmdf/serial/flush.c
+++ b/tests/projects/windows/driver/kmdf/serial/flush.c
diff --git a/tests/projects/wdk/kmdf/serial/immediat.c b/tests/projects/windows/driver/kmdf/serial/immediat.c
index 9fd7683af..9fd7683af 100644
--- a/tests/projects/wdk/kmdf/serial/immediat.c
+++ b/tests/projects/windows/driver/kmdf/serial/immediat.c
diff --git a/tests/projects/wdk/kmdf/serial/initunlo.c b/tests/projects/windows/driver/kmdf/serial/initunlo.c
index 07e7fb003..07e7fb003 100644
--- a/tests/projects/wdk/kmdf/serial/initunlo.c
+++ b/tests/projects/windows/driver/kmdf/serial/initunlo.c
diff --git a/tests/projects/wdk/kmdf/serial/ioctl.c b/tests/projects/windows/driver/kmdf/serial/ioctl.c
index 07ff2b147..07ff2b147 100644
--- a/tests/projects/wdk/kmdf/serial/ioctl.c
+++ b/tests/projects/windows/driver/kmdf/serial/ioctl.c
diff --git a/tests/projects/wdk/kmdf/serial/isr.c b/tests/projects/windows/driver/kmdf/serial/isr.c
index 806164a61..806164a61 100644
--- a/tests/projects/wdk/kmdf/serial/isr.c
+++ b/tests/projects/windows/driver/kmdf/serial/isr.c
diff --git a/tests/projects/wdk/kmdf/serial/log.c b/tests/projects/windows/driver/kmdf/serial/log.c
index 285c8b2f8..285c8b2f8 100644
--- a/tests/projects/wdk/kmdf/serial/log.c
+++ b/tests/projects/windows/driver/kmdf/serial/log.c
diff --git a/tests/projects/wdk/kmdf/serial/log.h b/tests/projects/windows/driver/kmdf/serial/log.h
index eedcd08f3..eedcd08f3 100644
--- a/tests/projects/wdk/kmdf/serial/log.h
+++ b/tests/projects/windows/driver/kmdf/serial/log.h
diff --git a/tests/projects/wdk/kmdf/serial/modmflow.c b/tests/projects/windows/driver/kmdf/serial/modmflow.c
index 1c71ae3fd..1c71ae3fd 100644
--- a/tests/projects/wdk/kmdf/serial/modmflow.c
+++ b/tests/projects/windows/driver/kmdf/serial/modmflow.c
diff --git a/tests/projects/wdk/kmdf/serial/openclos.c b/tests/projects/windows/driver/kmdf/serial/openclos.c
index 477f07ac1..477f07ac1 100644
--- a/tests/projects/wdk/kmdf/serial/openclos.c
+++ b/tests/projects/windows/driver/kmdf/serial/openclos.c
diff --git a/tests/projects/wdk/kmdf/serial/pnp.c b/tests/projects/windows/driver/kmdf/serial/pnp.c
index 8773f30ac..8773f30ac 100644
--- a/tests/projects/wdk/kmdf/serial/pnp.c
+++ b/tests/projects/windows/driver/kmdf/serial/pnp.c
diff --git a/tests/projects/wdk/kmdf/serial/power.c b/tests/projects/windows/driver/kmdf/serial/power.c
index 68aad3efa..68aad3efa 100644
--- a/tests/projects/wdk/kmdf/serial/power.c
+++ b/tests/projects/windows/driver/kmdf/serial/power.c
diff --git a/tests/projects/wdk/kmdf/serial/precomp.h b/tests/projects/windows/driver/kmdf/serial/precomp.h
index 7c7c5d5ef..7c7c5d5ef 100644
--- a/tests/projects/wdk/kmdf/serial/precomp.h
+++ b/tests/projects/windows/driver/kmdf/serial/precomp.h
diff --git a/tests/projects/wdk/kmdf/serial/precompsrc.c b/tests/projects/windows/driver/kmdf/serial/precompsrc.c
index 5944cf515..5944cf515 100644
--- a/tests/projects/wdk/kmdf/serial/precompsrc.c
+++ b/tests/projects/windows/driver/kmdf/serial/precompsrc.c
diff --git a/tests/projects/wdk/kmdf/serial/purge.c b/tests/projects/windows/driver/kmdf/serial/purge.c
index fcc32148e..fcc32148e 100644
--- a/tests/projects/wdk/kmdf/serial/purge.c
+++ b/tests/projects/windows/driver/kmdf/serial/purge.c
diff --git a/tests/projects/wdk/kmdf/serial/qsfile.c b/tests/projects/windows/driver/kmdf/serial/qsfile.c
index ad1604131..ad1604131 100644
--- a/tests/projects/wdk/kmdf/serial/qsfile.c
+++ b/tests/projects/windows/driver/kmdf/serial/qsfile.c
diff --git a/tests/projects/wdk/kmdf/serial/read.c b/tests/projects/windows/driver/kmdf/serial/read.c
index ab745fdd7..ab745fdd7 100644
--- a/tests/projects/wdk/kmdf/serial/read.c
+++ b/tests/projects/windows/driver/kmdf/serial/read.c
diff --git a/tests/projects/wdk/kmdf/serial/registry.c b/tests/projects/windows/driver/kmdf/serial/registry.c
index 5ab25955a..5ab25955a 100644
--- a/tests/projects/wdk/kmdf/serial/registry.c
+++ b/tests/projects/windows/driver/kmdf/serial/registry.c
diff --git a/tests/projects/wdk/kmdf/serial/serial.h b/tests/projects/windows/driver/kmdf/serial/serial.h
index fcbf9748f..fcbf9748f 100644
--- a/tests/projects/wdk/kmdf/serial/serial.h
+++ b/tests/projects/windows/driver/kmdf/serial/serial.h
diff --git a/tests/projects/wdk/kmdf/serial/serial.inx b/tests/projects/windows/driver/kmdf/serial/serial.inx
index 3322653b0..3322653b0 100644
--- a/tests/projects/wdk/kmdf/serial/serial.inx
+++ b/tests/projects/windows/driver/kmdf/serial/serial.inx
Binary files differ
diff --git a/tests/projects/wdk/kmdf/serial/serial.rc b/tests/projects/windows/driver/kmdf/serial/serial.rc
index 9fbb59de3..9fbb59de3 100644
--- a/tests/projects/wdk/kmdf/serial/serial.rc
+++ b/tests/projects/windows/driver/kmdf/serial/serial.rc
diff --git a/tests/projects/wdk/kmdf/serial/serialp.h b/tests/projects/windows/driver/kmdf/serial/serialp.h
index d363f3503..d363f3503 100644
--- a/tests/projects/wdk/kmdf/serial/serialp.h
+++ b/tests/projects/windows/driver/kmdf/serial/serialp.h
diff --git a/tests/projects/wdk/kmdf/serial/serlog.mc b/tests/projects/windows/driver/kmdf/serial/serlog.mc
index ee6935b67..ee6935b67 100644
--- a/tests/projects/wdk/kmdf/serial/serlog.mc
+++ b/tests/projects/windows/driver/kmdf/serial/serlog.mc
diff --git a/tests/projects/wdk/kmdf/serial/trace.h b/tests/projects/windows/driver/kmdf/serial/trace.h
index 5bd9d50ca..5bd9d50ca 100644
--- a/tests/projects/wdk/kmdf/serial/trace.h
+++ b/tests/projects/windows/driver/kmdf/serial/trace.h
diff --git a/tests/projects/wdk/kmdf/serial/utils.c b/tests/projects/windows/driver/kmdf/serial/utils.c
index a84136efe..a84136efe 100644
--- a/tests/projects/wdk/kmdf/serial/utils.c
+++ b/tests/projects/windows/driver/kmdf/serial/utils.c
diff --git a/tests/projects/wdk/kmdf/serial/waitmask.c b/tests/projects/windows/driver/kmdf/serial/waitmask.c
index c3139679e..c3139679e 100644
--- a/tests/projects/wdk/kmdf/serial/waitmask.c
+++ b/tests/projects/windows/driver/kmdf/serial/waitmask.c
diff --git a/tests/projects/wdk/kmdf/serial/wmi.c b/tests/projects/windows/driver/kmdf/serial/wmi.c
index 0076f4337..0076f4337 100644
--- a/tests/projects/wdk/kmdf/serial/wmi.c
+++ b/tests/projects/windows/driver/kmdf/serial/wmi.c
diff --git a/tests/projects/wdk/kmdf/serial/write.c b/tests/projects/windows/driver/kmdf/serial/write.c
index c67c062b4..c67c062b4 100644
--- a/tests/projects/wdk/kmdf/serial/write.c
+++ b/tests/projects/windows/driver/kmdf/serial/write.c
diff --git a/tests/projects/wdk/kmdf/serial/xmake.lua b/tests/projects/windows/driver/kmdf/serial/xmake.lua
index 53d59c650..53d59c650 100644
--- a/tests/projects/wdk/kmdf/serial/xmake.lua
+++ b/tests/projects/windows/driver/kmdf/serial/xmake.lua
diff --git a/tests/projects/wdk/umdf/echo/driver/device.c b/tests/projects/windows/driver/umdf/echo/driver/device.c
index bd522565f..bd522565f 100644
--- a/tests/projects/wdk/umdf/echo/driver/device.c
+++ b/tests/projects/windows/driver/umdf/echo/driver/device.c
diff --git a/tests/projects/wdk/umdf/echo/driver/device.h b/tests/projects/windows/driver/umdf/echo/driver/device.h
index 1e2c1f28e..1e2c1f28e 100644
--- a/tests/projects/wdk/umdf/echo/driver/device.h
+++ b/tests/projects/windows/driver/umdf/echo/driver/device.h
diff --git a/tests/projects/wdk/umdf/echo/driver/driver.c b/tests/projects/windows/driver/umdf/echo/driver/driver.c
index 2835aa1dd..2835aa1dd 100644
--- a/tests/projects/wdk/umdf/echo/driver/driver.c
+++ b/tests/projects/windows/driver/umdf/echo/driver/driver.c
diff --git a/tests/projects/wdk/umdf/echo/driver/driver.h b/tests/projects/windows/driver/umdf/echo/driver/driver.h
index 6539d6cf5..6539d6cf5 100644
--- a/tests/projects/wdk/umdf/echo/driver/driver.h
+++ b/tests/projects/windows/driver/umdf/echo/driver/driver.h
diff --git a/tests/projects/wdk/umdf/echo/driver/echoum.inx b/tests/projects/windows/driver/umdf/echo/driver/echoum.inx
index cae8b45fe..cae8b45fe 100644
--- a/tests/projects/wdk/umdf/echo/driver/echoum.inx
+++ b/tests/projects/windows/driver/umdf/echo/driver/echoum.inx
Binary files differ
diff --git a/tests/projects/wdk/umdf/echo/driver/queue.c b/tests/projects/windows/driver/umdf/echo/driver/queue.c
index e0f3d7b6b..e0f3d7b6b 100644
--- a/tests/projects/wdk/umdf/echo/driver/queue.c
+++ b/tests/projects/windows/driver/umdf/echo/driver/queue.c
diff --git a/tests/projects/wdk/umdf/echo/driver/queue.h b/tests/projects/windows/driver/umdf/echo/driver/queue.h
index 5c04dc8f7..5c04dc8f7 100644
--- a/tests/projects/wdk/umdf/echo/driver/queue.h
+++ b/tests/projects/windows/driver/umdf/echo/driver/queue.h
diff --git a/tests/projects/wdk/umdf/echo/exe/echoapp.cpp b/tests/projects/windows/driver/umdf/echo/exe/echoapp.cpp
index 47c0ae0a1..47c0ae0a1 100644
--- a/tests/projects/wdk/umdf/echo/exe/echoapp.cpp
+++ b/tests/projects/windows/driver/umdf/echo/exe/echoapp.cpp
diff --git a/tests/projects/wdk/umdf/echo/exe/public.h b/tests/projects/windows/driver/umdf/echo/exe/public.h
index defcded56..defcded56 100644
--- a/tests/projects/wdk/umdf/echo/exe/public.h
+++ b/tests/projects/windows/driver/umdf/echo/exe/public.h
diff --git a/tests/projects/wdk/umdf/echo/xmake.lua b/tests/projects/windows/driver/umdf/echo/xmake.lua
index 0a5ec9517..0a5ec9517 100644
--- a/tests/projects/wdk/umdf/echo/xmake.lua
+++ b/tests/projects/windows/driver/umdf/echo/xmake.lua
diff --git a/tests/projects/wdk/umdf/skeleton/Skeleton.rc b/tests/projects/windows/driver/umdf/skeleton/Skeleton.rc
index 0e202c4f5..0e202c4f5 100644
--- a/tests/projects/wdk/umdf/skeleton/Skeleton.rc
+++ b/tests/projects/windows/driver/umdf/skeleton/Skeleton.rc
diff --git a/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inx b/tests/projects/windows/driver/umdf/skeleton/UMDFSkeleton_OSR.inx
index 3da01ae62..3da01ae62 100644
--- a/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inx
+++ b/tests/projects/windows/driver/umdf/skeleton/UMDFSkeleton_OSR.inx
Binary files differ
diff --git a/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inx b/tests/projects/windows/driver/umdf/skeleton/UMDFSkeleton_Root.inx
index 63d9f94c5..63d9f94c5 100644
--- a/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inx
+++ b/tests/projects/windows/driver/umdf/skeleton/UMDFSkeleton_Root.inx
Binary files differ
diff --git a/tests/projects/wdk/umdf/skeleton/comsup.cpp b/tests/projects/windows/driver/umdf/skeleton/comsup.cpp
index fb0b0807c..fb0b0807c 100644
--- a/tests/projects/wdk/umdf/skeleton/comsup.cpp
+++ b/tests/projects/windows/driver/umdf/skeleton/comsup.cpp
diff --git a/tests/projects/wdk/umdf/skeleton/comsup.h b/tests/projects/windows/driver/umdf/skeleton/comsup.h
index ba4cd89c3..ba4cd89c3 100644
--- a/tests/projects/wdk/umdf/skeleton/comsup.h
+++ b/tests/projects/windows/driver/umdf/skeleton/comsup.h
diff --git a/tests/projects/wdk/umdf/skeleton/device.cpp b/tests/projects/windows/driver/umdf/skeleton/device.cpp
index 2efcd36f0..2efcd36f0 100644
--- a/tests/projects/wdk/umdf/skeleton/device.cpp
+++ b/tests/projects/windows/driver/umdf/skeleton/device.cpp
diff --git a/tests/projects/wdk/umdf/skeleton/device.h b/tests/projects/windows/driver/umdf/skeleton/device.h
index 26dd0e329..26dd0e329 100644
--- a/tests/projects/wdk/umdf/skeleton/device.h
+++ b/tests/projects/windows/driver/umdf/skeleton/device.h
diff --git a/tests/projects/wdk/umdf/skeleton/dllsup.cpp b/tests/projects/windows/driver/umdf/skeleton/dllsup.cpp
index e540452d9..e540452d9 100644
--- a/tests/projects/wdk/umdf/skeleton/dllsup.cpp
+++ b/tests/projects/windows/driver/umdf/skeleton/dllsup.cpp
diff --git a/tests/projects/wdk/umdf/skeleton/driver.cpp b/tests/projects/windows/driver/umdf/skeleton/driver.cpp
index d91b4b0b5..d91b4b0b5 100644
--- a/tests/projects/wdk/umdf/skeleton/driver.cpp
+++ b/tests/projects/windows/driver/umdf/skeleton/driver.cpp
diff --git a/tests/projects/wdk/umdf/skeleton/driver.h b/tests/projects/windows/driver/umdf/skeleton/driver.h
index e764f517d..e764f517d 100644
--- a/tests/projects/wdk/umdf/skeleton/driver.h
+++ b/tests/projects/windows/driver/umdf/skeleton/driver.h
diff --git a/tests/projects/wdk/umdf/skeleton/exports.def b/tests/projects/windows/driver/umdf/skeleton/exports.def
index 7d46558b7..7d46558b7 100644
--- a/tests/projects/wdk/umdf/skeleton/exports.def
+++ b/tests/projects/windows/driver/umdf/skeleton/exports.def
diff --git a/tests/projects/wdk/umdf/skeleton/internal.h b/tests/projects/windows/driver/umdf/skeleton/internal.h
index f338a9b6c..f338a9b6c 100644
--- a/tests/projects/wdk/umdf/skeleton/internal.h
+++ b/tests/projects/windows/driver/umdf/skeleton/internal.h
diff --git a/tests/projects/wdk/umdf/skeleton/xmake.lua b/tests/projects/windows/driver/umdf/skeleton/xmake.lua
index 8a48274ca..8a48274ca 100644
--- a/tests/projects/wdk/umdf/skeleton/xmake.lua
+++ b/tests/projects/windows/driver/umdf/skeleton/xmake.lua
diff --git a/tests/projects/wdk/wdm/msdsm/SampleDSM.inf b/tests/projects/windows/driver/wdm/msdsm/SampleDSM.inf
index f632f6e50..f632f6e50 100644
--- a/tests/projects/wdk/wdm/msdsm/SampleDSM.inf
+++ b/tests/projects/windows/driver/wdm/msdsm/SampleDSM.inf
Binary files differ
diff --git a/tests/projects/wdk/wdm/msdsm/dsmmain.c b/tests/projects/windows/driver/wdm/msdsm/dsmmain.c
index bdf875184..bdf875184 100644
--- a/tests/projects/wdk/wdm/msdsm/dsmmain.c
+++ b/tests/projects/windows/driver/wdm/msdsm/dsmmain.c
diff --git a/tests/projects/wdk/wdm/msdsm/dsmtrace.mof b/tests/projects/windows/driver/wdm/msdsm/dsmtrace.mof
index d9e8cf4cc..d9e8cf4cc 100644
--- a/tests/projects/wdk/wdm/msdsm/dsmtrace.mof
+++ b/tests/projects/windows/driver/wdm/msdsm/dsmtrace.mof
diff --git a/tests/projects/wdk/wdm/msdsm/intrface.c b/tests/projects/windows/driver/wdm/msdsm/intrface.c
index eeebf7f93..eeebf7f93 100644
--- a/tests/projects/wdk/wdm/msdsm/intrface.c
+++ b/tests/projects/windows/driver/wdm/msdsm/intrface.c
diff --git a/tests/projects/wdk/wdm/msdsm/msdsm.h b/tests/projects/windows/driver/wdm/msdsm/msdsm.h
index e1ddeb52d..e1ddeb52d 100644
--- a/tests/projects/wdk/wdm/msdsm/msdsm.h
+++ b/tests/projects/windows/driver/wdm/msdsm/msdsm.h
diff --git a/tests/projects/wdk/wdm/msdsm/msdsm.mof b/tests/projects/windows/driver/wdm/msdsm/msdsm.mof
index 53ee61392..53ee61392 100644
--- a/tests/projects/wdk/wdm/msdsm/msdsm.mof
+++ b/tests/projects/windows/driver/wdm/msdsm/msdsm.mof
diff --git a/tests/projects/wdk/wdm/msdsm/msdsm.rc b/tests/projects/windows/driver/wdm/msdsm/msdsm.rc
index 743640342..743640342 100644
--- a/tests/projects/wdk/wdm/msdsm/msdsm.rc
+++ b/tests/projects/windows/driver/wdm/msdsm/msdsm.rc
diff --git a/tests/projects/wdk/wdm/msdsm/msdsmdsm.mof b/tests/projects/windows/driver/wdm/msdsm/msdsmdsm.mof
index f85eea270..f85eea270 100644
--- a/tests/projects/wdk/wdm/msdsm/msdsmdsm.mof
+++ b/tests/projects/windows/driver/wdm/msdsm/msdsmdsm.mof
diff --git a/tests/projects/wdk/wdm/msdsm/precomp.h b/tests/projects/windows/driver/wdm/msdsm/precomp.h
index bca8595db..bca8595db 100644
--- a/tests/projects/wdk/wdm/msdsm/precomp.h
+++ b/tests/projects/windows/driver/wdm/msdsm/precomp.h
diff --git a/tests/projects/wdk/wdm/msdsm/precompsrc.c b/tests/projects/windows/driver/wdm/msdsm/precompsrc.c
index 5944cf515..5944cf515 100644
--- a/tests/projects/wdk/wdm/msdsm/precompsrc.c
+++ b/tests/projects/windows/driver/wdm/msdsm/precompsrc.c
diff --git a/tests/projects/wdk/wdm/msdsm/prototypes.h b/tests/projects/windows/driver/wdm/msdsm/prototypes.h
index ebcf42029..ebcf42029 100644
--- a/tests/projects/wdk/wdm/msdsm/prototypes.h
+++ b/tests/projects/windows/driver/wdm/msdsm/prototypes.h
diff --git a/tests/projects/wdk/wdm/msdsm/trace.h b/tests/projects/windows/driver/wdm/msdsm/trace.h
index b9449cc8f..b9449cc8f 100644
--- a/tests/projects/wdk/wdm/msdsm/trace.h
+++ b/tests/projects/windows/driver/wdm/msdsm/trace.h
diff --git a/tests/projects/wdk/wdm/msdsm/utils.c b/tests/projects/windows/driver/wdm/msdsm/utils.c
index 91d8f44ce..91d8f44ce 100644
--- a/tests/projects/wdk/wdm/msdsm/utils.c
+++ b/tests/projects/windows/driver/wdm/msdsm/utils.c
diff --git a/tests/projects/wdk/wdm/msdsm/wmi.c b/tests/projects/windows/driver/wdm/msdsm/wmi.c
index 0ee882192..0ee882192 100644
--- a/tests/projects/wdk/wdm/msdsm/wmi.c
+++ b/tests/projects/windows/driver/wdm/msdsm/wmi.c
diff --git a/tests/projects/wdk/wdm/msdsm/xmake.lua b/tests/projects/windows/driver/wdm/msdsm/xmake.lua
index 3c68aa1b8..3c68aa1b8 100644
--- a/tests/projects/wdk/wdm/msdsm/xmake.lua
+++ b/tests/projects/windows/driver/wdm/msdsm/xmake.lua
diff --git a/tests/projects/wdk/wdm/perfcounters/kcs.c b/tests/projects/windows/driver/wdm/perfcounters/kcs.c
index 9996addcb..9996addcb 100644
--- a/tests/projects/wdk/wdm/perfcounters/kcs.c
+++ b/tests/projects/windows/driver/wdm/perfcounters/kcs.c
diff --git a/tests/projects/wdk/wdm/perfcounters/kcs.h b/tests/projects/windows/driver/wdm/perfcounters/kcs.h
index f575b816d..f575b816d 100644
--- a/tests/projects/wdk/wdm/perfcounters/kcs.h
+++ b/tests/projects/windows/driver/wdm/perfcounters/kcs.h
diff --git a/tests/projects/wdk/wdm/perfcounters/kcs.man b/tests/projects/windows/driver/wdm/perfcounters/kcs.man
index a5a16ffbd..a5a16ffbd 100644
--- a/tests/projects/wdk/wdm/perfcounters/kcs.man
+++ b/tests/projects/windows/driver/wdm/perfcounters/kcs.man
diff --git a/tests/projects/wdk/wdm/perfcounters/kcs.rc b/tests/projects/windows/driver/wdm/perfcounters/kcs.rc
index 7ebb6b97b..7ebb6b97b 100644
--- a/tests/projects/wdk/wdm/perfcounters/kcs.rc
+++ b/tests/projects/windows/driver/wdm/perfcounters/kcs.rc
diff --git a/tests/projects/wdk/wdm/perfcounters/xmake.lua b/tests/projects/windows/driver/wdm/perfcounters/xmake.lua
index 83e4e4d9b..83e4e4d9b 100644
--- a/tests/projects/wdk/wdm/perfcounters/xmake.lua
+++ b/tests/projects/windows/driver/wdm/perfcounters/xmake.lua
diff --git a/tests/projects/winsdk/usbview/app.config b/tests/projects/windows/winsdk/usbview/app.config
index fe947d6fd..fe947d6fd 100644
--- a/tests/projects/winsdk/usbview/app.config
+++ b/tests/projects/windows/winsdk/usbview/app.config
diff --git a/tests/projects/winsdk/usbview/bang.ico b/tests/projects/windows/winsdk/usbview/bang.ico
index 90fe0f220..90fe0f220 100644
--- a/tests/projects/winsdk/usbview/bang.ico
+++ b/tests/projects/windows/winsdk/usbview/bang.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/codeanalysis.h b/tests/projects/windows/winsdk/usbview/codeanalysis.h
index 56fa54a1a..56fa54a1a 100644
--- a/tests/projects/winsdk/usbview/codeanalysis.h
+++ b/tests/projects/windows/winsdk/usbview/codeanalysis.h
diff --git a/tests/projects/winsdk/usbview/debug.c b/tests/projects/windows/winsdk/usbview/debug.c
index b73d727d5..b73d727d5 100644
--- a/tests/projects/winsdk/usbview/debug.c
+++ b/tests/projects/windows/winsdk/usbview/debug.c
diff --git a/tests/projects/winsdk/usbview/devnode.c b/tests/projects/windows/winsdk/usbview/devnode.c
index d9a3b8ecc..d9a3b8ecc 100644
--- a/tests/projects/winsdk/usbview/devnode.c
+++ b/tests/projects/windows/winsdk/usbview/devnode.c
diff --git a/tests/projects/winsdk/usbview/dispaud.c b/tests/projects/windows/winsdk/usbview/dispaud.c
index bbc16a912..bbc16a912 100644
--- a/tests/projects/winsdk/usbview/dispaud.c
+++ b/tests/projects/windows/winsdk/usbview/dispaud.c
diff --git a/tests/projects/winsdk/usbview/display.c b/tests/projects/windows/winsdk/usbview/display.c
index beead6d93..beead6d93 100644
--- a/tests/projects/winsdk/usbview/display.c
+++ b/tests/projects/windows/winsdk/usbview/display.c
diff --git a/tests/projects/winsdk/usbview/dispvid.c b/tests/projects/windows/winsdk/usbview/dispvid.c
index 537309721..537309721 100644
--- a/tests/projects/winsdk/usbview/dispvid.c
+++ b/tests/projects/windows/winsdk/usbview/dispvid.c
diff --git a/tests/projects/winsdk/usbview/enum.c b/tests/projects/windows/winsdk/usbview/enum.c
index 314a08806..314a08806 100644
--- a/tests/projects/winsdk/usbview/enum.c
+++ b/tests/projects/windows/winsdk/usbview/enum.c
diff --git a/tests/projects/winsdk/usbview/h264.c b/tests/projects/windows/winsdk/usbview/h264.c
index 108a1d540..108a1d540 100644
--- a/tests/projects/winsdk/usbview/h264.c
+++ b/tests/projects/windows/winsdk/usbview/h264.c
diff --git a/tests/projects/winsdk/usbview/h264.h b/tests/projects/windows/winsdk/usbview/h264.h
index 841318922..841318922 100644
--- a/tests/projects/winsdk/usbview/h264.h
+++ b/tests/projects/windows/winsdk/usbview/h264.h
diff --git a/tests/projects/winsdk/usbview/hub.ico b/tests/projects/windows/winsdk/usbview/hub.ico
index d0620df89..d0620df89 100644
--- a/tests/projects/winsdk/usbview/hub.ico
+++ b/tests/projects/windows/winsdk/usbview/hub.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/langidlist.h b/tests/projects/windows/winsdk/usbview/langidlist.h
index 0f2d90621..0f2d90621 100644
--- a/tests/projects/winsdk/usbview/langidlist.h
+++ b/tests/projects/windows/winsdk/usbview/langidlist.h
diff --git a/tests/projects/winsdk/usbview/monitor.ico b/tests/projects/windows/winsdk/usbview/monitor.ico
index e015959f6..e015959f6 100644
--- a/tests/projects/winsdk/usbview/monitor.ico
+++ b/tests/projects/windows/winsdk/usbview/monitor.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/port.ico b/tests/projects/windows/winsdk/usbview/port.ico
index 98c8aa04c..98c8aa04c 100644
--- a/tests/projects/winsdk/usbview/port.ico
+++ b/tests/projects/windows/winsdk/usbview/port.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/resource.h b/tests/projects/windows/winsdk/usbview/resource.h
index 921fa6a30..921fa6a30 100644
--- a/tests/projects/winsdk/usbview/resource.h
+++ b/tests/projects/windows/winsdk/usbview/resource.h
diff --git a/tests/projects/winsdk/usbview/split.cur b/tests/projects/windows/winsdk/usbview/split.cur
index 41d65e3c5..41d65e3c5 100644
--- a/tests/projects/winsdk/usbview/split.cur
+++ b/tests/projects/windows/winsdk/usbview/split.cur
Binary files differ
diff --git a/tests/projects/winsdk/usbview/ssport.ico b/tests/projects/windows/winsdk/usbview/ssport.ico
index e0f712ae6..e0f712ae6 100644
--- a/tests/projects/winsdk/usbview/ssport.ico
+++ b/tests/projects/windows/winsdk/usbview/ssport.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/ssusb.ico b/tests/projects/windows/winsdk/usbview/ssusb.ico
index 71f0ebe1d..71f0ebe1d 100644
--- a/tests/projects/winsdk/usbview/ssusb.ico
+++ b/tests/projects/windows/winsdk/usbview/ssusb.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/usb.ico b/tests/projects/windows/winsdk/usbview/usb.ico
index e615d3e24..e615d3e24 100644
--- a/tests/projects/winsdk/usbview/usb.ico
+++ b/tests/projects/windows/winsdk/usbview/usb.ico
Binary files differ
diff --git a/tests/projects/winsdk/usbview/usbdesc.h b/tests/projects/windows/winsdk/usbview/usbdesc.h
index 8b78a3c39..8b78a3c39 100644
--- a/tests/projects/winsdk/usbview/usbdesc.h
+++ b/tests/projects/windows/winsdk/usbview/usbdesc.h
diff --git a/tests/projects/winsdk/usbview/usbschema.hpp b/tests/projects/windows/winsdk/usbview/usbschema.hpp
index 1aac6d000..1aac6d000 100644
--- a/tests/projects/winsdk/usbview/usbschema.hpp
+++ b/tests/projects/windows/winsdk/usbview/usbschema.hpp
diff --git a/tests/projects/winsdk/usbview/usbviddesc.h b/tests/projects/windows/winsdk/usbview/usbviddesc.h
index f5a17164f..f5a17164f 100644
--- a/tests/projects/winsdk/usbview/usbviddesc.h
+++ b/tests/projects/windows/winsdk/usbview/usbviddesc.h
diff --git a/tests/projects/winsdk/usbview/uvcdesc.h b/tests/projects/windows/winsdk/usbview/uvcdesc.h
index f343fa731..f343fa731 100644
--- a/tests/projects/winsdk/usbview/uvcdesc.h
+++ b/tests/projects/windows/winsdk/usbview/uvcdesc.h
diff --git a/tests/projects/winsdk/usbview/uvcview.c b/tests/projects/windows/winsdk/usbview/uvcview.c
index 04b295292..04b295292 100644
--- a/tests/projects/winsdk/usbview/uvcview.c
+++ b/tests/projects/windows/winsdk/usbview/uvcview.c
diff --git a/tests/projects/winsdk/usbview/uvcview.h b/tests/projects/windows/winsdk/usbview/uvcview.h
index d5c3f5786..d5c3f5786 100644
--- a/tests/projects/winsdk/usbview/uvcview.h
+++ b/tests/projects/windows/winsdk/usbview/uvcview.h
diff --git a/tests/projects/winsdk/usbview/uvcview.rc b/tests/projects/windows/winsdk/usbview/uvcview.rc
index 6c7642ce3..6c7642ce3 100644
--- a/tests/projects/winsdk/usbview/uvcview.rc
+++ b/tests/projects/windows/winsdk/usbview/uvcview.rc
diff --git a/tests/projects/winsdk/usbview/vndrlist.h b/tests/projects/windows/winsdk/usbview/vndrlist.h
index ccf21267b..ccf21267b 100644
--- a/tests/projects/winsdk/usbview/vndrlist.h
+++ b/tests/projects/windows/winsdk/usbview/vndrlist.h
diff --git a/tests/projects/winsdk/usbview/xmake.lua b/tests/projects/windows/winsdk/usbview/xmake.lua
index 5d5639429..5d5639429 100644
--- a/tests/projects/winsdk/usbview/xmake.lua
+++ b/tests/projects/windows/winsdk/usbview/xmake.lua
diff --git a/tests/projects/winsdk/usbview/xmlhelper.cpp b/tests/projects/windows/winsdk/usbview/xmlhelper.cpp
index bac7d797b..bac7d797b 100644
--- a/tests/projects/winsdk/usbview/xmlhelper.cpp
+++ b/tests/projects/windows/winsdk/usbview/xmlhelper.cpp
diff --git a/tests/projects/winsdk/usbview/xmlhelper.h b/tests/projects/windows/winsdk/usbview/xmlhelper.h
index 1da37d97b..1da37d97b 100644
--- a/tests/projects/winsdk/usbview/xmlhelper.h
+++ b/tests/projects/windows/winsdk/usbview/xmlhelper.h
diff --git a/tests/projects/winsdk/windemo/main.cpp b/tests/projects/windows/winsdk/windemo/main.cpp
index a8340d936..a8340d936 100644
--- a/tests/projects/winsdk/windemo/main.cpp
+++ b/tests/projects/windows/winsdk/windemo/main.cpp
diff --git a/tests/projects/winsdk/windemo/resource.h b/tests/projects/windows/winsdk/windemo/resource.h
index 65ba8f31d..65ba8f31d 100644
--- a/tests/projects/winsdk/windemo/resource.h
+++ b/tests/projects/windows/winsdk/windemo/resource.h
diff --git a/tests/projects/winsdk/windemo/small.ico b/tests/projects/windows/winsdk/windemo/small.ico
index d551aa3aa..d551aa3aa 100644
--- a/tests/projects/winsdk/windemo/small.ico
+++ b/tests/projects/windows/winsdk/windemo/small.ico
Binary files differ
diff --git a/tests/projects/winsdk/windemo/stdafx.cpp b/tests/projects/windows/winsdk/windemo/stdafx.cpp
index 50daaa27d..50daaa27d 100644
--- a/tests/projects/winsdk/windemo/stdafx.cpp
+++ b/tests/projects/windows/winsdk/windemo/stdafx.cpp
diff --git a/tests/projects/winsdk/windemo/stdafx.h b/tests/projects/windows/winsdk/windemo/stdafx.h
index de0dfa3cd..de0dfa3cd 100644
--- a/tests/projects/winsdk/windemo/stdafx.h
+++ b/tests/projects/windows/winsdk/windemo/stdafx.h
diff --git a/tests/projects/winsdk/windemo/targetver.h b/tests/projects/windows/winsdk/windemo/targetver.h
index f583181df..f583181df 100644
--- a/tests/projects/winsdk/windemo/targetver.h
+++ b/tests/projects/windows/winsdk/windemo/targetver.h
diff --git a/tests/projects/winsdk/windemo/test b/tests/projects/windows/winsdk/windemo/test
index 33639f71c..33639f71c 100644
--- a/tests/projects/winsdk/windemo/test
+++ b/tests/projects/windows/winsdk/windemo/test
diff --git a/tests/projects/winsdk/windemo/test.h b/tests/projects/windows/winsdk/windemo/test.h
index e60f2eb7e..e60f2eb7e 100644
--- a/tests/projects/winsdk/windemo/test.h
+++ b/tests/projects/windows/winsdk/windemo/test.h
diff --git a/tests/projects/winsdk/windemo/test.ico b/tests/projects/windows/winsdk/windemo/test.ico
index d551aa3aa..d551aa3aa 100644
--- a/tests/projects/winsdk/windemo/test.ico
+++ b/tests/projects/windows/winsdk/windemo/test.ico
Binary files differ
diff --git a/tests/projects/winsdk/windemo/test.rc b/tests/projects/windows/winsdk/windemo/test.rc
index 9ef96ba63..9ef96ba63 100644
--- a/tests/projects/winsdk/windemo/test.rc
+++ b/tests/projects/windows/winsdk/windemo/test.rc
diff --git a/tests/projects/winsdk/windemo/xmake.lua b/tests/projects/windows/winsdk/windemo/xmake.lua
index 1f492822e..1f492822e 100644
--- a/tests/projects/winsdk/windemo/xmake.lua
+++ b/tests/projects/windows/winsdk/windemo/xmake.lua
diff --git a/tests/projects/xmake_cli/xmake/src/xmake.rc b/tests/projects/xmake_cli/xmake/src/xmake.rc
index 0d737ebc3..2167c8f25 100644
--- a/tests/projects/xmake_cli/xmake/src/xmake.rc
+++ b/tests/projects/xmake_cli/xmake/src/xmake.rc
@@ -26,7 +26,7 @@ BEGIN
VALUE "FileDescription", "XMake build utility"
VALUE "FileVersion", XM_CONFIG_VERSION "+" STR(XM_CONFIG_VERSION_BUILD)
VALUE "InternalName", "xmake"
- VALUE "LegalCopyright", "Copyright (C) 2015-2020 Ruki Wang, tboox.org, xmake.io\nCopyright (C) 2005-2015 Mike Pall, luajit.org"
+ VALUE "LegalCopyright", "Copyright (C) 2015-present Ruki Wang, tboox.org, xmake.io"
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "xmake.exe"
VALUE "ProductName", "XMake"
diff --git a/tests/run.lua b/tests/run.lua
index 572e31e9f..00c18ff07 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -10,9 +10,7 @@ if option.get("verbose") then table.insert(params, "-v") end
if option.get("diagnosis") then table.insert(params, "-D") end
function _run_test(script)
-
assert(script:endswith("test.lua"))
-
os.execv("xmake", table.join("lua", params, path.join(os.scriptdir(), "runner.lua"), script))
end
@@ -23,10 +21,14 @@ function _run_test_filter(name)
local root = path.absolute(os.scriptdir())
-- find the test script
for _, script in ipairs(os.files(path.join(root, "**", name, "**", "test.lua"))) do
- table.insert(tests, path.absolute(script))
+ if not script:find(".xmake", 1, true) then
+ table.insert(tests, path.absolute(script))
+ end
end
for _, script in ipairs(os.files(path.join(root, name, "**", "test.lua"))) do
- table.insert(tests, path.absolute(script))
+ if not script:find(".xmake", 1, true) then
+ table.insert(tests, path.absolute(script))
+ end
end
for _, script in ipairs(os.files(path.join(root, "**", name, "test.lua"))) do
table.insert(tests, path.absolute(script))
diff --git a/xmake/actions/build/build.lua b/xmake/actions/build/build.lua
index 0fc15fd81..598d4b2cf 100644
--- a/xmake/actions/build/build.lua
+++ b/xmake/actions/build/build.lua
@@ -24,12 +24,12 @@ import("core.project.config")
import("core.project.project")
import("private.async.jobpool")
import("private.async.runjobs")
+import("private.utils.batchcmds")
import("core.base.hashset")
-- clean target for rebuilding
function _clean_target(target)
- local targetkind = target:kind()
- if targetkind ~= "phony" and targetkind ~= "object" then
+ if target:targetfile() then
os.tryrm(target:symbolfile())
os.tryrm(target:targetfile())
end
@@ -50,11 +50,20 @@ function _add_batchjobs_builtin(batchjobs, rootjob, target)
script(target, {progress = (index * 100) / total})
end, {rootjob = job or rootjob})
end
+ else
+ local buildcmd = r:script("buildcmd")
+ if buildcmd then
+ job = batchjobs:addjob("rule/" .. r:name() .. "/build", function (index, total)
+ local batchcmds_ = batchcmds.new({target = target})
+ buildcmd(target, batchcmds_, {progress = (index * 100) / total})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end, {rootjob = job or rootjob})
+ end
end
end
-- uses the builtin target script
- if not job and not target:is_phony() then
+ if not job and (target:is_static() or target:is_binary() or target:is_shared() or target:is_object()) then
job, job_leaf = import("kinds." .. target:kind(), {anonymous = true})(batchjobs, rootjob, target)
end
job = job or rootjob
@@ -118,6 +127,13 @@ function _add_batchjobs_for_target(batchjobs, rootjob, target)
local after_build = r:script("build_after")
if after_build then
after_build(target, {progress = progress})
+ else
+ local after_buildcmd = r:script("buildcmd_after")
+ if after_buildcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ after_buildcmd(target, batchcmds_, {progress = progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
end
@@ -152,6 +168,13 @@ function _add_batchjobs_for_target(batchjobs, rootjob, target)
local before_build = r:script("build_before")
if before_build then
before_build(target, {progress = progress})
+ else
+ local before_buildcmd = r:script("buildcmd_before")
+ if before_buildcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ before_buildcmd(target, batchcmds_, {progress = progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
end
end, {rootjob = job_build_leaf})
@@ -177,7 +200,7 @@ function _add_batchjobs_for_target_and_deps(batchjobs, rootjob, jobrefs, target)
end
-- get batch jobs, @note we need export it for private.diagnosis.dump_buildjobs
-function get_batchjobs(targetname)
+function get_batchjobs(targetname, group_pattern)
-- get root targets
local targets_root = {}
@@ -187,7 +210,8 @@ function get_batchjobs(targetname)
local depset = hashset.new()
local targets = {}
for _, target in pairs(project.targets()) do
- if target:is_default() or option.get("all") then
+ local group = target:get("group")
+ if (target:is_default() and not group_pattern) or option.get("all") or (group_pattern and group and group:match(group_pattern)) then
for _, depname in ipairs(target:get("deps")) do
depset:insert(depname)
end
@@ -211,14 +235,14 @@ function get_batchjobs(targetname)
end
-- the main entry
-function main(targetname)
+function main(targetname, group_pattern)
-- build all jobs
- local batchjobs = get_batchjobs(targetname)
+ local batchjobs = get_batchjobs(targetname, group_pattern)
if batchjobs and batchjobs:size() > 0 then
local curdir = os.curdir()
runjobs("build", batchjobs, {comax = option.get("jobs") or 1, on_exit = function (errors)
- import("private.utils.progress")
+ import("utils.progress")
if errors and progress.showing_without_scroll() then
print("")
end
diff --git a/xmake/actions/build/build_files.lua b/xmake/actions/build/build_files.lua
index dd89ea311..2f8af59ec 100644
--- a/xmake/actions/build/build_files.lua
+++ b/xmake/actions/build/build_files.lua
@@ -114,7 +114,7 @@ function _add_batchjobs_for_target_and_deps(batchjobs, rootjob, jobrefs, target,
end
-- get batch jobs
-function _get_batchjobs(targetname, filepatterns)
+function _get_batchjobs(targetname, group_pattern, filepatterns)
-- get root targets
local targets_root = {}
@@ -124,7 +124,8 @@ function _get_batchjobs(targetname, filepatterns)
local depset = hashset.new()
local targets = {}
for _, target in pairs(project.targets()) do
- if target:is_default() or option.get("all") then
+ local group = target:get("group")
+ if (target:is_default() and not group_pattern) or option.get("all") or (group_pattern and group and group:match(group_pattern)) then
for _, depname in ipairs(target:get("deps")) do
depset:insert(depname)
end
@@ -192,13 +193,13 @@ function _get_file_patterns(sourcefiles)
end
-- the main entry
-function main(targetname, sourcefiles)
+function main(targetname, group_pattern, sourcefiles)
-- convert all sourcefiles to lua pattern
local filepatterns = _get_file_patterns(sourcefiles)
-- build all jobs
- local batchjobs = _get_batchjobs(targetname, filepatterns)
+ local batchjobs = _get_batchjobs(targetname, group_pattern, filepatterns)
if batchjobs and batchjobs:size() > 0 then
local curdir = os.curdir()
runjobs("build_files", batchjobs, {comax = option.get("jobs") or 1, curdir = curdir, count_as_index = true})
diff --git a/xmake/actions/build/kinds/binary.lua b/xmake/actions/build/kinds/binary.lua
index dd72fc21a..26544c311 100644
--- a/xmake/actions/build/kinds/binary.lua
+++ b/xmake/actions/build/kinds/binary.lua
@@ -24,7 +24,8 @@ import("core.theme.theme")
import("core.tool.linker")
import("core.tool.compiler")
import("core.project.depend")
-import("private.utils.progress")
+import("utils.progress")
+import("private.utils.batchcmds")
import("object", {alias = "add_batchjobs_for_object"})
-- do link target
@@ -87,6 +88,13 @@ function _on_link_target(target, opt)
on_link(target, opt)
done = true
end
+ local on_linkcmd = r:script("linkcmd")
+ if on_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ on_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ done = true
+ end
end
if done then return end
@@ -109,6 +117,12 @@ function _link_target(target, opt)
if before_link then
before_link(target, opt)
end
+ local before_linkcmd = r:script("linkcmd_before")
+ if before_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ before_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
-- on link
@@ -126,6 +140,12 @@ function _link_target(target, opt)
if after_link then
after_link(target, opt)
end
+ local after_linkcmd = r:script("linkcmd_after")
+ if after_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ after_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
end
diff --git a/xmake/actions/build/kinds/shared.lua b/xmake/actions/build/kinds/shared.lua
index 2d2d9e507..99a6d1db5 100644
--- a/xmake/actions/build/kinds/shared.lua
+++ b/xmake/actions/build/kinds/shared.lua
@@ -24,7 +24,8 @@ import("core.theme.theme")
import("core.tool.linker")
import("core.tool.compiler")
import("core.project.depend")
-import("private.utils.progress")
+import("utils.progress")
+import("private.utils.batchcmds")
import("object", {alias = "add_batchjobs_for_object"})
-- do link target
@@ -102,6 +103,13 @@ function _on_link_target(target, opt)
on_link(target, opt)
done = true
end
+ local on_linkcmd = r:script("linkcmd")
+ if on_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ on_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ done = true
+ end
end
if done then return end
@@ -124,6 +132,12 @@ function _link_target(target, opt)
if before_link then
before_link(target, opt)
end
+ local before_linkcmd = r:script("linkcmd_before")
+ if before_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ before_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
-- on link
@@ -141,6 +155,12 @@ function _link_target(target, opt)
if after_link then
after_link(target, opt)
end
+ local after_linkcmd = r:script("linkcmd_after")
+ if after_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ after_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
end
diff --git a/xmake/actions/build/kinds/static.lua b/xmake/actions/build/kinds/static.lua
index 91fba6ed5..56a900572 100644
--- a/xmake/actions/build/kinds/static.lua
+++ b/xmake/actions/build/kinds/static.lua
@@ -24,7 +24,8 @@ import("core.theme.theme")
import("core.tool.linker")
import("core.tool.compiler")
import("core.project.depend")
-import("private.utils.progress")
+import("utils.progress")
+import("private.utils.batchcmds")
import("object", {alias = "add_batchjobs_for_object"})
-- do link target
@@ -102,6 +103,13 @@ function _on_link_target(target, opt)
on_link(target, opt)
done = true
end
+ local on_linkcmd = r:script("linkcmd")
+ if on_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ on_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ done = true
+ end
end
if done then return end
@@ -124,6 +132,12 @@ function _link_target(target, opt)
if before_link then
before_link(target, opt)
end
+ local before_linkcmd = r:script("linkcmd_before")
+ if before_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ before_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
-- on link
@@ -141,6 +155,12 @@ function _link_target(target, opt)
if after_link then
after_link(target, opt)
end
+ local after_linkcmd = r:script("linkcmd_after")
+ if after_linkcmd then
+ local batchcmds_ = batchcmds.new({target = target})
+ after_linkcmd(target, batchcmds_, {progress = opt.progress})
+ batchcmds_:runcmds({dryrun = option.get("dry-run")})
+ end
end
end
diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua
index 864f88185..c355ae4ae 100644
--- a/xmake/actions/build/main.lua
+++ b/xmake/actions/build/main.lua
@@ -27,7 +27,7 @@ import("core.project.config")
import("core.project.project")
import("core.platform.platform")
import("core.theme.theme")
-import("private.utils.progress")
+import("utils.progress")
import("build")
import("build_files")
import("cleaner")
@@ -92,6 +92,16 @@ function _do_project_rules(scriptname, opt)
end
end
+-- do build
+function _do_build(targetname, group_pattern)
+ local sourcefiles = option.get("files")
+ if sourcefiles then
+ build_files(targetname, group_pattern, sourcefiles)
+ else
+ build(targetname, group_pattern)
+ end
+end
+
-- main
function main()
@@ -106,10 +116,14 @@ function main()
-- lock the whole project
project.lock()
- -- get the target name
- local targetname = option.get("target")
-
-- config it first
+ local targetname
+ local group_pattern = option.get("group")
+ if group_pattern then
+ group_pattern = "^" .. path.pattern(group_pattern) .. "$"
+ else
+ targetname = option.get("target")
+ end
task.run("config", {target = targetname}, {disable_dump = true})
-- enter project directory
@@ -126,12 +140,7 @@ function main()
_do_project_rules("build_before")
-- do build
- local sourcefiles = option.get("files")
- if sourcefiles then
- build_files(targetname, sourcefiles)
- else
- build(targetname)
- end
+ _do_build(targetname, group_pattern)
end,
catch
@@ -144,6 +153,8 @@ function main()
-- raise
if errors then
raise(errors)
+ elseif group_pattern then
+ raise("build targets with group(%s) failed!", group_pattern)
elseif targetname then
raise("build target: %s failed!", targetname)
else
diff --git a/xmake/actions/build/xmake.lua b/xmake/actions/build/xmake.lua
index 3323ac5b1..a1ed27952 100644
--- a/xmake/actions/build/xmake.lua
+++ b/xmake/actions/build/xmake.lua
@@ -44,10 +44,15 @@ task("build")
{'b', "build", "k", nil , "Build target. This is default building mode and optional." }
, {'r', "rebuild", "k", nil , "Rebuild the target." }
, {'a', "all", "k", nil , "Build all targets." }
+ , {'g', "group", "kv", nil , "Build all targets of the given group. It support path pattern matching.",
+ "e.g.",
+ " xmake -g test",
+ " xmake -g test_*",
+ " xmake --group=benchmark/*" }
, {nil, "dry-run", "k", nil , "Dry run to build target." }
, {}
- , {'j', "jobs", "kv", tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2)),
+ , {'j', "jobs", "kv", tostring(os.default_njob()),
"Set the number of parallel compilation jobs." }
, {nil, "linkjobs", "kv", nil, "Set the number of parallel link jobs." }
, {'w', "warning", "k", false , "Enable the warnings output." }
diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua
index e9e574545..c508d0566 100644
--- a/xmake/actions/clean/main.lua
+++ b/xmake/actions/clean/main.lua
@@ -162,7 +162,7 @@ function main()
-- enter project directory
local oldir = os.cd(project.directory())
- -- clean the current target
+ -- clean target
_clean(targetname)
-- unlock the whole project
diff --git a/xmake/actions/config/configfiles.lua b/xmake/actions/config/configfiles.lua
index 33a44c1a8..72891136a 100644
--- a/xmake/actions/config/configfiles.lua
+++ b/xmake/actions/config/configfiles.lua
@@ -167,7 +167,9 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets)
-- get variables from the target
for name, value in pairs(target:get("configvar")) do
if variables[name] == nil then
- variables[name] = table.unwrap(value)
+ value = table.unwrap(value)
+ variables[name] = value
+ variables["__extraconf_" .. name] = target:extraconf("configvar." .. name, value)
end
end
@@ -176,6 +178,7 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets)
for name, value in pairs(opt:get("configvar")) do
if variables[name] == nil then
variables[name] = table.unwrap(value)
+ variables["__extraconf_" .. name] = target:extraconf("configvar." .. name, value)
end
end
end
@@ -185,6 +188,7 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets)
for name, value in pairs(pkg:get("configvar")) do
if variables[name] == nil then
variables[name] = table.unwrap(value)
+ variables["__extraconf_" .. name] = target:extraconf("configvar." .. name, value)
end
end
end
@@ -236,6 +240,7 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets)
-- get variable value
local value = variables[variable]
+ local extraconf = variables["__extraconf_" .. variable]
if isdefine then
if value == nil then
value = ("/* #undef %s */"):format(variable)
@@ -248,7 +253,26 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets)
elseif type(value) == "number" then
value = ("#define %s %d"):format(variable, value)
elseif type(value) == "string" then
- value = ("#define %s \"%s\""):format(variable, value)
+ local quote = true
+ local escape = false
+ if extraconf then
+ -- disable to wrap quote, @see https://github.com/xmake-io/xmake/issues/1694
+ if extraconf.quote == false then
+ quote = false
+ end
+ -- escape path seperator when with quote, @see https://github.com/xmake-io/xmake/issues/1872
+ if quote and extraconf.escape then
+ escape = true
+ end
+ end
+ if quote then
+ if escape then
+ value = value:gsub("\\", "\\\\")
+ end
+ value = ("#define %s \"%s\""):format(variable, value)
+ else
+ value = ("#define %s %s"):format(variable, value)
+ end
else
raise("unknown variable(%s) type: %s", variable, type(value))
end
diff --git a/xmake/actions/config/main.lua b/xmake/actions/config/main.lua
index dcf5986dc..23ef3fe43 100644
--- a/xmake/actions/config/main.lua
+++ b/xmake/actions/config/main.lua
@@ -316,7 +316,8 @@ force to build in current directory via run `xmake -P .`]], os.projectdir())
-- merge configuration from the given import file
local importfile = option.get("import")
- if importfile and os.isfile(importfile) then
+ if importfile then
+ assert(os.isfile(importfile), "%s not found!", importfile)
if config.load(importfile) then
options_changed = true
end
diff --git a/xmake/actions/config/menuconf.lua b/xmake/actions/config/menuconf.lua
index 2f8706e4e..8ca87d918 100644
--- a/xmake/actions/config/menuconf.lua
+++ b/xmake/actions/config/menuconf.lua
@@ -253,6 +253,7 @@ function app:_basic_configs(cache)
if type(values) == "function" then
values = values(false, {menuconf = true})
end
+ values = table.wrap(values)
for idx, value in ipairs(values) do
if default == value then
default = idx
@@ -331,6 +332,7 @@ function app:_project_configs(cache)
local values = opt:get("values")
if values then
kind = "choice"
+ values = table.wrap(values)
for idx, value in ipairs(values) do
if default == value then
default = idx
diff --git a/xmake/actions/create/main.lua b/xmake/actions/create/main.lua
index 611c0a57c..560b3b457 100644
--- a/xmake/actions/create/main.lua
+++ b/xmake/actions/create/main.lua
@@ -76,13 +76,13 @@ function _create_project(language, templateid, targetname)
end
-- xmake.lua exists?
- if os.isfile(path.join(projectdir, "xmake.lua")) then
+ if os.isfile(path.join(projectdir, "xmake.lua")) and not option.get("force") then
raise("project (${underline}%s/xmake.lua${reset}) exists!", projectdir)
end
-- empty project?
os.tryrm(path.join(projectdir, ".xmake"))
- if not os.emptydir(projectdir) then
+ if not os.emptydir(projectdir) and not option.get("force") then
-- otherwise, check whether it is empty
raise("project directory (${underline}%s${reset}) is not empty!", projectdir)
end
diff --git a/xmake/actions/create/xmake.lua b/xmake/actions/create/xmake.lua
index 005bdf6be..812411e03 100644
--- a/xmake/actions/create/xmake.lua
+++ b/xmake/actions/create/xmake.lua
@@ -38,7 +38,8 @@ task("create")
-- options
, options =
{
- {'l', "language", "kv", "c++", "The project language"
+ {'f', "force", "k", nil, "Force to create project in a non-empty directory."}
+ , {'l', "language", "kv", "c++", "The project language"
-- show the description of all languages
, values = function (complete, opt)
diff --git a/xmake/actions/global/menuconf.lua b/xmake/actions/global/menuconf.lua
index c191f829c..6fcfb1841 100644
--- a/xmake/actions/global/menuconf.lua
+++ b/xmake/actions/global/menuconf.lua
@@ -232,6 +232,7 @@ function app:_global_configs(cache)
if type(values) == "function" then
values = values()
end
+ values = table.wrap(values)
for idx, value in ipairs(values) do
if default == value then
default = idx
diff --git a/xmake/actions/global/xmake.lua b/xmake/actions/global/xmake.lua
index b98305418..9765412a0 100644
--- a/xmake/actions/global/xmake.lua
+++ b/xmake/actions/global/xmake.lua
@@ -18,79 +18,61 @@
-- @file xmake.lua
--
--- define task
task("global")
-
- -- set category
set_category("action")
-
- -- on run
on_run("main")
-
- -- set menu
set_menu {
- -- usage
- usage = "xmake global|g [options] [target]"
-
- -- description
- , description = "Configure the global options for xmake."
-
- -- xmake g
- , shortname = 'g'
-
- -- options
- , options =
- {
- {'c', "clean", "k" , nil , "Clean the cached configure and configure all again." }
- , {nil, "menu", "k" , nil , "Configure with a menu-driven user interface." }
- , {category = "."}
- , {nil, "theme", "kv", "default" , "The theme name."
- , values = function ()
- return import("core.theme.theme.names")()
- end}
- , {nil, "debugger", "kv", "auto" , "The debugger program path." }
- , {category = "Build Configuration"}
- , {nil, "build_warning", "kv", nil , "Enable the warnings output by default when building." }
- , {nil, "cachedir", "kv", nil , "The global cache directory." }
+ usage = "xmake global|g [options] [target]",
+ description = "Configure the global options for xmake.",
+ shortname = 'g',
+ options = {
+ {'c', "clean", "k" , nil , "Clean the cached configure and configure all again." },
+ {nil, "menu", "k" , nil , "Configure with a menu-driven user interface." },
+ {category = "."},
+ {nil, "theme", "kv", "default" , "The theme name."
+ , values = function ()
+ return import("core.theme.theme.names")()
+ end},
+ {nil, "debugger", "kv", "auto" , "The debugger program path." },
+ {nil, "ccache", "kv", nil , "Enable or disable the c/c++ compiler cache." },
+ {category = "Build Configuration"},
+ {nil, "build_warning", "kv", nil , "Enable the warnings output by default when building." },
+ {nil, "cachedir", "kv", nil , "The global cache directory." },
-- network configuration
- , {category = "Network Configuration"}
- , {nil, "network", "kv", "public" , "Set the network mode."
- , values = {"public", "private"} }
- , {'x', "proxy", "kv", nil , "Use proxy on given port. [protocol://]host[:port]"
- , " e.g."
- , " - xmake g --proxy='http://host:port'"
- , " - xmake g --proxy='https://host:port'"
- , " - xmake g --proxy='socks5://host:port'" }
- , {nil, "proxy_hosts", "kv", nil , "Only enable proxy for the given hosts list, it will enable all if be unset,"
- , "and we can pass match pattern to list:"
- , " e.g."
- , " - xmake g --proxy_hosts='github.com,gitlab.*,*.xmake.io'"}
- , {nil, "proxy_pac", "kv", "pac.lua" , "Set the auto proxy configuration file."
- , " e.g."
- , " - xmake g --proxy_pac=pac.lua (in $(globaldir) or absolute path)"
- , " - function main(url, host)"
- , " if host == 'github.com' then"
- , " return true"
- , " end"
- , " end"}
+ {category = "Network Configuration"},
+ {nil, "network", "kv", "public" , "Set the network mode."
+ , values = {"public", "private"} },
+ {'x', "proxy", "kv", nil , "Use proxy on given port. [protocol://]host[:port]"
+ , " e.g."
+ , " - xmake g --proxy='http://host:port'"
+ , " - xmake g --proxy='https://host:port'"
+ , " - xmake g --proxy='socks5://host:port'" },
+ {nil, "proxy_hosts", "kv", nil , "Only enable proxy for the given hosts list, it will enable all if be unset,"
+ , "and we can pass match pattern to list:"
+ , " e.g."
+ , " - xmake g --proxy_hosts='github.com,gitlab.*,*.xmake.io'"},
+ {nil, "proxy_pac", "kv", "pac.lua" , "Set the auto proxy configuration file."
+ , " e.g."
+ , " - xmake g --proxy_pac=pac.lua (in $(globaldir) or absolute path)"
+ , " - function main(url, host)"
+ , " if host == 'github.com' then"
+ , " return true"
+ , " end"
+ , " end"},
-- package configuration
- , {category = "Package Configuration"}
- , {nil, "pkg_searchdirs", "kv", nil , "The search directories of the remote package."
- , " e.g."
- , " - xmake g --pkg_searchdirs=/dir1" .. path.envsep() .. "/dir2"}
- , {nil, "pkg_installdir", "kv", nil , "The install root directory of the remote package." }
+ {category = "Package Configuration"},
+ {nil, "pkg_searchdirs", "kv", nil , "The search directories of the remote package."
+ , " e.g."
+ , " - xmake g --pkg_searchdirs=/dir1" .. path.envsep() .. "/dir2"},
+ {nil, "pkg_installdir", "kv", nil , "The install root directory of the remote package."},
-- show platform menu options
- , {category = "Platform Configuration"}
- , function ()
-
- -- import platform menu
- import("core.platform.menu")
-
- -- get global menu options
- return menu.options("global")
+ {category = "Platform Configuration"},
+ function ()
+ import("core.platform.menu")
+ return menu.options("global")
end
}
}
diff --git a/xmake/actions/install/install_admin.lua b/xmake/actions/install/install_admin.lua
index 1f0103d27..c2b57f05d 100644
--- a/xmake/actions/install/install_admin.lua
+++ b/xmake/actions/install/install_admin.lua
@@ -28,6 +28,8 @@ import("install")
-- install
function main(targetname, installdir, prefix)
+ local verbose = option.get("verbose")
+
-- enter project directory
os.cd(project.directory())
@@ -40,6 +42,9 @@ function main(targetname, installdir, prefix)
-- save the current option and push a new option context
option.save()
+ -- preserve verbose option
+ option.set("verbose", verbose)
+
-- pass installdir to option
if installdir then
option.set("installdir", installdir)
diff --git a/xmake/actions/install/main.lua b/xmake/actions/install/main.lua
index 40ba15cc3..82534ffe0 100644
--- a/xmake/actions/install/main.lua
+++ b/xmake/actions/install/main.lua
@@ -46,7 +46,7 @@ function _check_targets(targetname)
-- filter and check targets with builtin-install script
local targetnames = {}
for _, target in ipairs(targets) do
- if not target:is_phony() and target:is_enabled() and not target:script("install") then
+ if target:targetfile() and target:is_enabled() and not target:script("install") then
local targetfile = target:targetfile()
if targetfile and not os.isfile(targetfile) then
table.insert(targetnames, target:name())
@@ -110,7 +110,7 @@ function main()
if sudo.has() and option.get("admin") then
-- install target with administrator permission
- sudo.runl(path.join(os.scriptdir(), "install_admin.lua"), {targetname or (option.get("all") and "__all" or "__def"), option.get("installdir"), option.get("prefix")})
+ sudo.execl(path.join(os.scriptdir(), "install_admin.lua"), {targetname or (option.get("all") and "__all" or "__def"), option.get("installdir"), option.get("prefix")})
cprint("${color.success}install ok!")
ok = true
end
diff --git a/xmake/actions/package/local/main.lua b/xmake/actions/package/local/main.lua
index 21c807091..1a3a0a190 100644
--- a/xmake/actions/package/local/main.lua
+++ b/xmake/actions/package/local/main.lua
@@ -24,7 +24,7 @@ import("core.base.task")
import("core.project.rule")
import("core.project.config")
import("core.project.project")
-import("lib.luajit.bit")
+import("core.base.bit")
-- get link deps
function _get_linkdeps(target)
@@ -32,7 +32,6 @@ function _get_linkdeps(target)
for _, depname in ipairs(target:get("deps")) do
local dep = project.target(depname)
if not ((target:is_binary() or target:is_shared()) and dep:is_static()) then
- table.join2(linkdeps, _get_linkdeps(dep))
table.insert(linkdeps, dep:name())
end
end
@@ -156,17 +155,22 @@ function _package_library(target)
end
file:print("")
file:print([[
+ add_configs("shared", {description = "Build shared library.", default = %s, type = "boolean", readonly = true})
+
on_load(function (package)
package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode()))
end)
on_fetch(function (package)
local result = {}
+ local libfiledir = (package:config("shared") and package:is_plat("windows", "mingw")) and "bin" or "lib"
result.links = "%s"
result.linkdirs = package:installdir("lib")
result.includedirs = package:installdir("include")
+ result.libfiles = path.join(package:installdir(libfiledir), "%s")
return result
- end)]], target:linkname(),
+ end)]], target:is_shared() and "true" or "false",
+ target:linkname(),
path.filename(targetfile))
file:close()
end
@@ -175,14 +179,76 @@ function _package_library(target)
print("package(%s): %s generated", packagename, packagedir)
end
+-- package headeronly library
+function _package_headeronly(target)
+
+ -- get the output directory
+ local outputdir = option.get("outputdir") or config.buildir()
+ local packagename = target:name():lower()
+ if #packagename > 1 and bit.band(packagename:byte(2), 0xc0) == 0x80 then
+ wprint("package(%s): cannot generate package, becauese it contains unicode characters!", packagename)
+ return
+ end
+ local packagedir = path.join(outputdir, "packages", packagename:sub(1, 1), packagename)
+ local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include")
+
+ -- copy headers
+ local srcheaders, dstheaders = target:headerfiles(headerdir)
+ if srcheaders and dstheaders then
+ local i = 1
+ for _, srcheader in ipairs(srcheaders) do
+ local dstheader = dstheaders[i]
+ if dstheader then
+ os.vcp(srcheader, dstheader)
+ end
+ i = i + 1
+ end
+ end
+
+ -- generate xmake.lua
+ local file = io.open(path.join(packagedir, "xmake.lua"), "w")
+ if file then
+ local deps = _get_linkdeps(target)
+ file:print("package(\"%s\")", packagename)
+ local homepage = option.get("homepage")
+ if homepage then
+ file:print(" set_homepage(\"%s\")", homepage)
+ end
+ local description = option.get("description") or ("The " .. packagename .. " package")
+ file:print(" set_description(\"%s\")", description)
+ if target:license() then
+ file:print(" set_license(\"%s\")", target:license())
+ end
+ if #deps > 0 then
+ file:print(" add_deps(\"%s\")", table.concat(deps, "\", \""))
+ end
+ file:print("")
+ file:print([[
+ on_load(function (package)
+ package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode()))
+ end)
+
+ on_fetch(function (package)
+ local result = {}
+ result.includedirs = package:installdir("include")
+ return result
+ end)]])
+ file:close()
+ end
+
+ -- show tips
+ print("package(%s): %s generated", packagename, packagedir)
+end
+
-- do package target
function _do_package_target(target)
if not target:is_phony() then
local scripts =
{
- binary = _package_binary
- , static = _package_library
- , shared = _package_library
+ binary = _package_binary
+ , static = _package_library
+ , shared = _package_library
+ , headeronly = _package_headeronly
}
local kind = target:kind()
assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind)
diff --git a/xmake/actions/package/oldpkg/main.lua b/xmake/actions/package/oldpkg/main.lua
index d47d8d474..4dea87c4b 100644
--- a/xmake/actions/package/oldpkg/main.lua
+++ b/xmake/actions/package/oldpkg/main.lua
@@ -35,12 +35,14 @@ function _package_library(target)
local targetname = target:name()
-- copy the library file to the output directory
- os.vcp(target:targetfile(), format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(target:targetfile())))
+ if not target:is_headeronly() then
+ os.vcp(target:targetfile(), format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(target:targetfile())))
- -- copy the symbol file to the output directory
- local symbolfile = target:symbolfile()
- if os.isfile(symbolfile) then
- os.vcp(symbolfile, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(symbolfile)))
+ -- copy the symbol file to the output directory
+ local symbolfile = target:symbolfile()
+ if os.isfile(symbolfile) then
+ os.vcp(symbolfile, format("%s/%s.pkg/$(plat)/$(arch)/lib/$(mode)/%s", outputdir, targetname, path.filename(symbolfile)))
+ end
end
-- copy *.lib for shared/windows (*.dll) target
@@ -78,8 +80,10 @@ function _package_library(target)
file:print("option(\"%s\")", targetname)
file:print(" set_showmenu(true)")
file:print(" set_category(\"package\")")
- file:print(" add_links(\"%s\")", target:basename())
- file:write(" add_linkdirs(\"$(plat)/$(arch)/lib/$(mode)\")\n")
+ if not target:is_headeronly() then
+ file:print(" add_links(\"%s\")", target:basename())
+ file:write(" add_linkdirs(\"$(plat)/$(arch)/lib/$(mode)\")\n")
+ end
file:write(" add_includedirs(\"$(plat)/$(arch)/include\")\n")
local languages = target:get("languages")
if languages then
@@ -94,9 +98,10 @@ function _do_package_target(target)
if not target:is_phony() then
local scripts =
{
- binary = function (target) end
- , static = _package_library
- , shared = _package_library
+ binary = function (target) end
+ , static = _package_library
+ , shared = _package_library
+ , headeronly = _package_library
}
local kind = target:kind()
assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind)
diff --git a/xmake/actions/package/remote/main.lua b/xmake/actions/package/remote/main.lua
index 064141b56..9db86e8d5 100644
--- a/xmake/actions/package/remote/main.lua
+++ b/xmake/actions/package/remote/main.lua
@@ -24,7 +24,19 @@ import("core.base.task")
import("core.project.rule")
import("core.project.config")
import("core.project.project")
-import("lib.luajit.bit")
+import("core.base.bit")
+
+-- get link deps
+function _get_linkdeps(target)
+ local linkdeps = {}
+ for _, depname in ipairs(target:get("deps")) do
+ local dep = project.target(depname)
+ if not ((target:is_binary() or target:is_shared()) and dep:is_static()) then
+ table.insert(linkdeps, dep:name())
+ end
+ end
+ return linkdeps
+end
-- package remote
function _package_remote(target)
@@ -41,13 +53,12 @@ function _package_remote(target)
-- generate xmake.lua
local file = io.open(path.join(packagedir, "xmake.lua"), "w")
if file then
- local deps = {}
- for _, dep in ipairs(target:orderdeps()) do
- table.insert(deps, dep:name())
- end
+ local deps = _get_linkdeps(target)
file:print("package(\"%s\")", packagename)
if target:is_binary() then
file:print(" set_kind(\"binary\")")
+ elseif target:is_headeronly() then
+ file:print(" set_kind(\"library\", {headeronly = true})")
end
local homepage = option.get("homepage")
if homepage then
@@ -93,9 +104,10 @@ function _package_target(target)
if not target:is_phony() then
local scripts =
{
- binary = _package_remote
- , static = _package_remote
- , shared = _package_remote
+ binary = _package_remote
+ , static = _package_remote
+ , shared = _package_remote
+ , headeronly = _package_remote
}
local kind = target:kind()
assert(scripts[kind], "this target(%s) with kind(%s) can not be packaged!", target:name(), kind)
diff --git a/xmake/actions/require/main.lua b/xmake/actions/require/main.lua
index eb0e2014e..41b9a7eac 100644
--- a/xmake/actions/require/main.lua
+++ b/xmake/actions/require/main.lua
@@ -118,7 +118,7 @@ function main()
scan(option.get("requires"))
- -- install and update all outdated package dependencies by default if no arguments
+ -- install and upgrade all outdated package dependencies by default if no arguments
else
install(option.get("requires"))
end
diff --git a/xmake/actions/require/xmake.lua b/xmake/actions/require/xmake.lua
index a9d4db32c..3ffd17fe3 100644
--- a/xmake/actions/require/xmake.lua
+++ b/xmake/actions/require/xmake.lua
@@ -46,7 +46,7 @@ task("require")
" $ xmake require --clean",
" $ xmake require --clean zlib tbox pcr*" }
, {'f', "force", "k", nil, "Force to reinstall all package dependencies." }
- , {'j', "jobs", "kv", tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2)),
+ , {'j', "jobs", "kv", tostring(os.default_njob()),
"Set the number of parallel compilation jobs." }
, {nil, "linkjobs", "kv", nil, "Set the number of parallel link jobs." }
, {nil, "shallow", "k", nil, "Does not install dependent packages." }
@@ -72,6 +72,7 @@ task("require")
, {'s', "search", "k", nil, "Search for the given packages from repositories.",
"e.g.",
" $ xmake require --search tbox" }
+ , {nil, "upgrade", "k", nil, "Upgrade the installed packages." }
, {nil, "uninstall", "k", nil, "Uninstall the installed packages.",
"e.g.",
" $ xmake require --uninstall",
diff --git a/xmake/actions/run/main.lua b/xmake/actions/run/main.lua
index a74845f95..72983c446 100644
--- a/xmake/actions/run/main.lua
+++ b/xmake/actions/run/main.lua
@@ -48,10 +48,10 @@ function _do_run_target(target)
-- add run environments
local addrunenvs, setrunenvs = make_runenvs(target)
for name, values in pairs(addrunenvs) do
- os.addenv(name, unpack(table.wrap(values)))
+ os.addenv(name, table.unpack(table.wrap(values)))
end
for name, value in pairs(setrunenvs) do
- os.setenv(name, unpack(table.wrap(value)))
+ os.setenv(name, table.unpack(table.wrap(value)))
end
-- debugging?
@@ -144,17 +144,19 @@ function _run(target)
end
-- check targets
-function _check_targets(targetname)
+function _check_targets(targetname, group_pattern)
-- get targets
local targets = {}
- if targetname and not targetname:startswith("__") then
+ if targetname then
table.insert(targets, project.target(targetname))
else
- -- install default or all targets
for _, target in ipairs(project.ordertargets()) do
- if (target:is_default() or option.get("all")) and target:is_binary() then
- table.insert(targets, target)
+ if target:is_binary() then
+ local group = target:get("group")
+ if (target:is_default() and not group_pattern) or option.get("all") or (group_pattern and group and group:match(group_pattern)) then
+ table.insert(targets, target)
+ end
end
end
end
@@ -162,7 +164,7 @@ function _check_targets(targetname)
-- filter and check targets with builtin-run script
local targetnames = {}
for _, target in ipairs(targets) do
- if not target:is_phony() and target:is_enabled() and not target:script("run") then
+ if target:targetfile() and target:is_enabled() and not target:script("run") then
local targetfile = target:targetfile()
if targetfile and not os.isfile(targetfile) then
table.insert(targetnames, target:name())
@@ -179,14 +181,18 @@ end
-- main
function main()
- -- get the target name
- local targetname = option.get("target")
-
-- config it first
+ local targetname
+ local group_pattern = option.get("group")
+ if group_pattern then
+ group_pattern = "^" .. path.pattern(group_pattern) .. "$"
+ else
+ targetname = option.get("target")
+ end
task.run("config", {target = targetname, require = "n", verbose = false})
-- check targets first
- _check_targets(targetname)
+ _check_targets(targetname, group_pattern)
-- enter project directory
local oldir = os.cd(project.directory())
@@ -195,10 +201,12 @@ function main()
if targetname then
_run(project.target(targetname))
else
- -- run default or all binary targets
for _, target in ipairs(project.ordertargets()) do
- if (target:is_default() or option.get("all")) and target:is_binary() then
- _run(target)
+ if target:is_binary() then
+ local group = target:get("group")
+ if (target:is_default() and not group_pattern) or option.get("all") or (group_pattern and group and group:match(group_pattern)) then
+ _run(target)
+ end
end
end
end
diff --git a/xmake/actions/run/xmake.lua b/xmake/actions/run/xmake.lua
index 83d4d3f9f..7c5b1086e 100644
--- a/xmake/actions/run/xmake.lua
+++ b/xmake/actions/run/xmake.lua
@@ -43,13 +43,20 @@ task("run")
{
{'d', "debug", "k", nil , "Run and debug the given target." }
, {'a', "all", "k", nil , "Run all targets." }
+ , {'g', "group", "kv", nil , "Run all targets of the given group. It support path pattern matching.",
+ "e.g.",
+ " xmake run -g test",
+ " xmake run -g test_*",
+ " xmake run --group=benchmark/*" }
, {'w', "workdir", "kv", nil , "Work directory of running targets, default is folder of targetfile",
"e.g.",
- " --workdir=.",
- " --workdir=`pwd`" }
+ " xmake run -w .",
+ " xmake run --workdir=`pwd`" }
, {}
, {nil, "target", "v", nil , "The target name. It will run all default targets if this parameter is not specified."
- , values = function (complete, opt) return import("private.utils.complete_helper.runable_targets")(complete, opt) end }
+ , values = function (complete, opt)
+ return import("private.utils.complete_helper.runable_targets")(complete, opt)
+ end }
, {nil, "arguments", "vs", nil , "The target arguments" }
}
diff --git a/xmake/actions/uninstall/main.lua b/xmake/actions/uninstall/main.lua
index eedde054e..3e6769c24 100644
--- a/xmake/actions/uninstall/main.lua
+++ b/xmake/actions/uninstall/main.lua
@@ -81,7 +81,7 @@ function main()
if sudo.has() and option.get("admin") then
-- uninstall target with administrator permission
- sudo.runl(path.join(os.scriptdir(), "uninstall_admin.lua"), {targetname or "__all", option.get("installdir"), option.get("prefix")})
+ sudo.execl(path.join(os.scriptdir(), "uninstall_admin.lua"), {targetname or "__all", option.get("installdir"), option.get("prefix")})
-- trace
cprint("${color.success}uninstall ok!")
diff --git a/xmake/actions/uninstall/uninstall_admin.lua b/xmake/actions/uninstall/uninstall_admin.lua
index c30a16a01..f597dea11 100644
--- a/xmake/actions/uninstall/uninstall_admin.lua
+++ b/xmake/actions/uninstall/uninstall_admin.lua
@@ -28,6 +28,8 @@ import("uninstall")
-- uninstall
function main(targetname, installdir, prefix)
+ local verbose = option.get("verbose")
+
-- enter project directory
os.cd(project.directory())
@@ -40,6 +42,9 @@ function main(targetname, installdir, prefix)
-- save the current option and push a new option context
option.save()
+ -- preserve verbose option
+ option.set("verbose", verbose)
+
-- pass installdir to option
if installdir then
option.set("installdir", installdir)
diff --git a/xmake/actions/update/main.lua b/xmake/actions/update/main.lua
index ed403f47a..7db7eda58 100644
--- a/xmake/actions/update/main.lua
+++ b/xmake/actions/update/main.lua
@@ -158,9 +158,18 @@ function _install(sourcedir)
if os.isfile(win_installer_name) then
-- /D sets the default installation directory ($INSTDIR), overriding InstallDir and InstallDirRegKey. It must be the last parameter used in the command line and must not contain any quotes, even if the path contains spaces. Only absolute paths are supported.
local params = ("/D=" .. os.programdir()):split("%s", { strict = true })
- local testfile = path.join(os.programdir(), "temp-install")
- local no_admin = os.trycp(path.join(os.programdir(), "scripts", "run.vbs"), testfile)
- os.tryrm(testfile)
+ -- @see https://github.com/xmake-io/xmake/issues/1576
+ local no_admin = try {function () return winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\XMake;NoAdmin") end}
+ if no_admin == nil then
+ no_admin = try {function () return winos.registry_query("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\XMake;NoAdmin") end}
+ end
+ if no_admin ~= nil then
+ no_admin = tostring(no_admin):lower() == "true"
+ else
+ local testfile = path.join(os.programdir(), "temp-install")
+ no_admin = os.trycp(path.join(os.programdir(), "scripts", "run.vbs"), testfile)
+ os.tryrm(testfile)
+ end
if no_admin then table.insert(params, 1, "/NOADMIN") end
-- need UAC?
if winos:version():gt("winxp") then
diff --git a/xmake/core/_xmake_main.lua b/xmake/core/_xmake_main.lua
index ec1492ca8..b35768058 100644
--- a/xmake/core/_xmake_main.lua
+++ b/xmake/core/_xmake_main.lua
@@ -34,7 +34,15 @@ xmake._PROJECT_DIR = _PROJECT_DIR
xmake._PROJECT_FILE = "xmake.lua"
xmake._WORKING_DIR = os.curdir()
xmake._FEATURES = _FEATURES
+xmake._LUAJIT = _LUAJIT
+-- In order to be compatible with updates from lower versions of engine core
+-- @see https://github.com/xmake-io/xmake/issues/1694#issuecomment-925507210
+if xmake._LUAJIT == nil then
+ xmake._LUAJIT = true
+end
+
+-- load the given lua file
function _loadfile_impl(filepath, mode, opt)
-- init options
@@ -112,8 +120,8 @@ function loadfile(filepath, mode, opt)
return script, errors
end
--- init package path
-table.insert(package.loaders, 2, function(v)
+-- init package path, package.searchers for lua5.4
+table.insert(package.loaders or package.searchers, 2, function(v)
local filepath = xmake._PROGRAM_DIR .. "/core/" .. v .. ".lua"
local script, serr = _loadfile_impl(filepath)
if not script then
diff --git a/xmake/core/base/bit.lua b/xmake/core/base/bit.lua
new file mode 100644
index 000000000..768722318
--- /dev/null
+++ b/xmake/core/base/bit.lua
@@ -0,0 +1,21 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file bit.lua
+--
+
+return (xmake._LUAJIT and require("bit") or require("base/compat/bit"))
diff --git a/xmake/core/base/bytes.lua b/xmake/core/base/bytes.lua
index 340b21cd0..bb65d0cfc 100644
--- a/xmake/core/base/bytes.lua
+++ b/xmake/core/base/bytes.lua
@@ -23,17 +23,12 @@ local bytes = bytes or {}
local _instance = _instance or {}
-- load modules
-local bit = require('bit')
-local ffi = require('ffi')
+local bit = require("base/bit")
local os = require("base/os")
local utils = require("base/utils")
local todisplay = require("base/todisplay")
-
--- define ffi interfaces
-ffi.cdef[[
- void* malloc(size_t size);
- void free(void* data);
-]]
+local libc = require("base/libc")
+local table = require("base/table")
-- new a bytes instance
--
@@ -48,7 +43,7 @@ ffi.cdef[[
--
function _instance.new(...)
local args = {...}
- local arg1, arg2, arg3 = unpack(args)
+ local arg1, arg2, arg3 = table.unpack(args)
local instance = table.inherit(_instance)
if type(arg1) == "number" then
local size = arg1
@@ -57,10 +52,10 @@ function _instance.new(...)
local ptr = arg2
local manage = arg3
if manage then
- instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ptr), ffi.C.free)
+ instance._CDATA = libc.dataptr(ptr, {gc = true})
instance._MANAGED = true
else
- instance._CDATA = ffi.cast("unsigned char*", ptr)
+ instance._CDATA = libc.dataptr(ptr)
instance._MANAGED = false
end
else
@@ -75,11 +70,11 @@ function _instance.new(...)
os.raise("invalid arguments #2 for bytes(size, ...), cdata, string, number or nil expected!")
end
end
- local ptr = ffi.C.malloc(size)
+ local ptr = libc.malloc(size, {gc = true})
if init then
- ffi.fill(ptr, size, init)
+ libc.memset(ptr, init, size)
end
- instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ptr), ffi.C.free)
+ instance._CDATA = ptr
instance._MANAGED = true
end
instance._SIZE = size
@@ -88,7 +83,7 @@ function _instance.new(...)
-- bytes(str): mounts a buffer from the given string
local str = arg1
instance._SIZE = #str
- instance._CDATA = ffi.cast("unsigned char*", str)
+ instance._CDATA = libc.dataptr(str)
instance._REF = str -- keep ref for GC
instance._MANAGED = false
instance._READONLY = true
@@ -102,7 +97,7 @@ function _instance.new(...)
os.raise("incorrect bounds(%d-%d) for bytes(...)!", start, last)
end
instance._SIZE = last - start + 1
- instance._CDATA = b:cdata() - 1 + start
+ instance._CDATA = b:cdata() -1 + start
instance._REF = b -- keep lua ref for GC
instance._MANAGED = false
instance._READONLY = b:readonly()
@@ -112,10 +107,10 @@ function _instance.new(...)
for _, b in ipairs(args) do
instance._SIZE = instance._SIZE + b:size()
end
- instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ffi.C.malloc(instance._SIZE)), ffi.C.free)
+ instance._CDATA = libc.malloc(instance._SIZE, {gc = true})
local offset = 0
for _, b in ipairs(args) do
- ffi.copy(instance._CDATA + offset, b:cdata(), b:size())
+ libc.memcpy(instance._CDATA + offset, b:cdata(), b:size())
offset = offset + b:size()
end
instance._MANAGED = true
@@ -127,10 +122,10 @@ function _instance.new(...)
for _, b in ipairs(args) do
instance._SIZE = instance._SIZE + b:size()
end
- instance._CDATA = ffi.gc(ffi.cast("unsigned char*", ffi.C.malloc(instance._SIZE)), ffi.C.free)
+ instance._CDATA = libc.malloc(instance._SIZE, {gc = true})
local offset = 0
for _, b in ipairs(args) do
- ffi.copy(instance._CDATA + offset, b._CDATA, b:size())
+ libc.memcpy(instance._CDATA + offset, b._CDATA, b:size())
offset = offset + b:size()
end
instance._MANAGED = true
@@ -144,7 +139,7 @@ function _instance.new(...)
os.raise("incorrect bounds(%d-%d)!", start, last)
end
instance._SIZE = last - start + 1
- instance._CDATA = b:cdata() - 1 + start
+ instance._CDATA = b:cdata() -1 + start
instance._REF = b -- keep lua ref for GC
instance._MANAGED = false
instance._READONLY = b:readonly()
@@ -181,7 +176,7 @@ end
-- get data address
function _instance:caddr()
- return tonumber(ffi.cast('unsigned long long', self:cdata()))
+ return libc.ptraddr(self:cdata())
end
-- readonly?
@@ -216,7 +211,7 @@ function _instance:copy(src)
if src:size() ~= self:size() then
os.raise("%s: cannot copy bytes, src and dst must have same size(%d->%d)!", self, src:size(), self:size())
end
- ffi.copy(self:cdata(), src:cdata(), self:size())
+ libc.memcpy(self:cdata(), src:cdata(), self:size())
return self
end
@@ -330,7 +325,7 @@ end
-- convert bytes to string
function _instance:str(i, j)
local offset = i and i - 1 or 0
- return ffi.string(self:cdata() + offset, (j or self:size()) - offset)
+ return libc.strndup(self:cdata() + offset, (j or self:size()) - offset)
end
-- get uint8 value
@@ -396,7 +391,7 @@ function _instance:__index(key)
if key < 1 or key > self:size() then
os.raise("%s: index(%d/%d) out of bounds!", self, key, self:size())
end
- return self._CDATA[key - 1]
+ return libc.byteof(self._CDATA, key - 1)
elseif type(key) == "table" then
local start, last = key[1], key[2]
return self:slice(start, last)
@@ -417,7 +412,7 @@ function _instance:__newindex(key, value)
if key < 1 or key > self:size() then
os.raise("%s: index(%d/%d) out of bounds!", self, key, self:size())
end
- self._CDATA[key - 1] = value
+ libc.setbyte(self._CDATA, key - 1, value)
return
elseif type(key) == "table" then
local start, last = key[1], key[2]
@@ -453,6 +448,14 @@ function _instance:__todisplay()
return "bytes${reset}(" .. todisplay(self:size()) .. ") <${color.dump.number}" .. table.concat(parts, " ") .. (self:size() > 8 and "${reset} ..>" or "${reset}>")
end
+-- it's only called for lua runtime, because bytes is not userdata
+function _instance:__gc()
+ if self._MANAGED and self._CDATA then
+ libc.free(self._CDATA)
+ self._CDATA = nil
+ end
+end
+
-- new an bytes instance
function bytes.new(...)
return _instance.new(...)
diff --git a/xmake/core/base/colors.lua b/xmake/core/base/colors.lua
index 942f1f081..9c2016b10 100644
--- a/xmake/core/base/colors.lua
+++ b/xmake/core/base/colors.lua
@@ -164,7 +164,7 @@ function colors.rainbow24(index, seed, freq, spread)
local blue = math.sin(freq * index + 4 * math.pi / 3) * 127 + 128
-- make code
- return string.format("%d;%d;%d", red, green, blue)
+ return string.format("%d;%d;%d", math.floor(red), math.floor(green), math.floor(blue))
end
-- make rainbow color256 code by the index of characters (16-256)
@@ -184,7 +184,7 @@ function colors.rainbow256(index, seed, freq, spread)
index = seed + index / spread
-- make color code
- local code = (freq * index) % 240 + 18
+ local code = math.floor((freq * index) % 240 + 18)
-- make code
return string.format("#%d", code)
@@ -337,6 +337,8 @@ function colors.translate(str, opt)
-- unknown code, regard as plain text
table.insert(text_buffer, block)
end
+ elseif not opt.ignore_unknown then
+ table.insert(text_buffer, block)
end
end
diff --git a/xmake/core/base/compat/bit.lua b/xmake/core/base/compat/bit.lua
new file mode 100644
index 000000000..c4a018382
--- /dev/null
+++ b/xmake/core/base/compat/bit.lua
@@ -0,0 +1,73 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file bit.lua
+--
+
+-- define module: bit
+local bit = bit or {}
+
+-- bit/and operation
+function bit.band(a, b)
+ return a & b
+end
+
+-- bit/or operation
+function bit.bor(a, b)
+ return a | b
+end
+
+-- bit/xor operation
+function bit.bxor(a, b)
+ return a ~ b
+end
+
+-- bit/not operation
+function bit.bnot(a)
+ return ~a
+end
+
+-- bit/lshift operation
+function bit.lshift(a, b)
+ return a << b
+end
+
+-- bit/rshift operation
+function bit.rshift(a, b)
+ return a >> b
+end
+
+-- tobit operation
+function bit.tobit(x)
+ return x & 0xffffffff
+end
+
+-- tohex operation
+function bit.tohex(x, n)
+ n = n or 8
+ local up
+ if n <= 0 then
+ if n == 0 then return '' end
+ up = true
+ n = - n
+ end
+ x = x & (16 ^ n - 1)
+ return ('%0'..n..(up and 'X' or 'x')):format(x)
+end
+
+-- return module: bit
+return bit
diff --git a/xmake/core/base/compat/env.lua b/xmake/core/base/compat/env.lua
new file mode 100644
index 000000000..b7956866e
--- /dev/null
+++ b/xmake/core/base/compat/env.lua
@@ -0,0 +1,98 @@
+-- (c) 2012 David Manura. Licensed under the same terms as Lua 5.1/5.2 (MIT license).
+-- Permission is hereby granted, free of charge, to any person obtaining a copy
+-- of this software and associated documentation files (the "Software"), to deal
+-- in the Software without restriction, including without limitation the rights
+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-- copies of the Software, and to permit persons to whom the Software is
+-- furnished to do so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in
+-- all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+-- THE SOFTWARE.
+--
+-- @author David Manura, ruki
+-- @file env.lua
+--
+
+-- define module: env
+local env = env or {}
+
+-- from https://github.com/davidm/lua-inspect/blob/master/lib/luainspect/compat_env.lua
+if _G.setfenv then -- Lua 5.1
+ env.setfenv = _G.setfenv
+ env.getfenv = _G.getfenv
+else -- >= Lua 5.2
+ -- helper function for `getfenv`/`setfenv`
+ local function envlookup(f)
+ local name, val
+ local up = 0
+ local unknown
+ repeat
+ up = up + 1; name, val = debug.getupvalue(f, up)
+ if name == '' then unknown = true end
+ until name == '_ENV' or name == nil
+ if name ~= '_ENV' then
+ up = nil
+ if unknown then error("upvalues not readable in Lua 5.2 when debug info missing", 3) end
+ end
+ return (name == '_ENV') and up, val, unknown
+ end
+
+ -- helper function for `getfenv`/`setfenv`
+ local function envhelper(f, name)
+ if type(f) == 'number' then
+ if f < 0 then
+ error(("bad argument #1 to '%s' (level must be non-negative)"):format(name), 3)
+ elseif f < 1 then
+ error("thread environments unsupported in Lua 5.2", 3) --[*]
+ end
+ f = debug.getinfo(f+2, 'f').func
+ elseif type(f) ~= 'function' then
+ error(("bad argument #1 to '%s' (number expected, got %s)"):format(type(name, f)), 2)
+ end
+ return f
+ end
+ -- [*] might simulate with table keyed by coroutine.running()
+
+ -- 5.1 style `setfenv` implemented in 5.2
+ function env.setfenv(f, t)
+ local f = envhelper(f, 'setfenv')
+ local up, val, unknown = envlookup(f)
+ if up then
+ debug.upvaluejoin(f, up, function() return up end, 1) -- unique upvalue [*]
+ debug.setupvalue(f, up, t)
+ else
+ local what = debug.getinfo(f, 'S').what
+ if what ~= 'Lua' and what ~= 'main' then -- not Lua func
+ error("'setfenv' cannot change environment of given object", 2)
+ end -- else ignore no _ENV upvalue (warning: incompatible with 5.1)
+ end
+ end
+ -- [*] http://lua-users.org/lists/lua-l/2010-06/msg00313.html
+
+ -- 5.1 style `getfenv` implemented in 5.2
+ function env.getfenv(f)
+ if f == 0 or f == nil then return _G end -- simulated behavior
+ local f = envhelper(f, 'setfenv')
+ local up, val = envlookup(f)
+ if not up then return _G end -- simulated behavior [**]
+ return val
+ end
+ -- [**] possible reasons: no _ENV upvalue, C function
+
+ -- register to global
+ _G.setfenv = env.setfenv
+ _G.getfenv = env.getfenv
+ debug.setfenv = env.setfenv
+ debug.getfenv = env.getfenv
+end
+
+-- return module: env
+return env
diff --git a/xmake/core/base/deprecated/interpreter.lua b/xmake/core/base/deprecated/interpreter.lua
deleted file mode 100644
index 4213de8a0..000000000
--- a/xmake/core/base/deprecated/interpreter.lua
+++ /dev/null
@@ -1,140 +0,0 @@
---!A cross-platform build utility based on Lua
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
--- Copyright (C) 2015-present, TBOOX Open Source Group.
---
--- @author ruki
--- @file deprecated_interpreter.lua
---
-
--- define module: deprecated_interpreter
-local deprecated_interpreter = deprecated_interpreter or {}
-
--- load modules
-local os = require("base/os")
-local path = require("base/path")
-local table = require("base/table")
-local utils = require("base/utils")
-local string = require("base/string")
-local deprecated = require("base/deprecated")
-local sandbox = require("sandbox/sandbox")
-
--- register api for set_scope()
-function deprecated_interpreter:api_register_set_scope(...)
-
- -- check
- assert(self)
-
- -- define implementation
- local implementation = function (self, scopes, scope_kind, scope_name)
-
- -- init scope for kind
- local scope_for_kind = scopes[scope_kind] or {}
- scopes[scope_kind] = scope_for_kind
-
- -- deprecated
- if not scope_name:startswith("__") then
- deprecated.add("%s(\"%s\")", "set_%s(\"%s\")", scope_kind, scope_name)
- end
-
- -- check
- if not scope_for_kind[scope_name] then
- utils.error("set_%s(\"%s\") failed, %s not found!", scope_kind, scope_name, scope_name)
- os.raise("please uses add_%s(\"%s\") first!", scope_kind, scope_name)
- end
-
- -- init scope for name
- scope_for_kind[scope_name] = scope_for_kind[scope_name] or {}
-
- -- save the current scope
- scopes._CURRENT = scope_for_kind[scope_name]
-
- -- update the current scope kind
- scopes._CURRENT_KIND = scope_kind
-
- end
-
- -- register implementation
- self:_api_register_scope_api(nil, "set", implementation, ...)
-end
-
--- register api for add_scope()
-function deprecated_interpreter:api_register_add_scope(...)
-
- -- check
- assert(self)
-
- -- define implementation
- local implementation = function (self, scopes, scope_kind, scope_name)
-
- -- init scope for kind
- local scope_for_kind = scopes[scope_kind] or {}
- scopes[scope_kind] = scope_for_kind
-
- -- deprecated
- if not scope_name:startswith("__") then
- deprecated.add("%s(\"%s\")", "add_%s(\"%s\")", scope_kind, scope_name)
- end
-
- -- check
- if scope_for_kind[scope_name] then
- utils.error("add_%s(\"%s\") failed, %s have been defined!", scope_kind, scope_name, scope_name)
- os.raise("please uses set_%s(\"%s\")!", scope_kind, scope_name)
- end
-
- -- init scope for name
- scope_for_kind[scope_name] = scope_for_kind[scope_name] or {}
-
- -- save the current scope
- scopes._CURRENT = scope_for_kind[scope_name]
-
- -- update the current scope kind
- scopes._CURRENT_KIND = scope_kind
-
- end
-
- -- register implementation
- self:_api_register_scope_api(nil, "add", implementation, ...)
-end
-
--- register api for set_script
-function deprecated_interpreter:api_register_set_script(scope_kind, ...)
-
- -- check
- assert(self)
-
- -- define implementation
- local implementation = function (self, scope, name, script)
-
- -- deprecated
- deprecated.add("on_%s()", "set_%s()", name)
-
- -- make sandbox instance with the given script
- local instance, errors = sandbox.new(script, self:filter(), self:rootdir())
- if not instance then
- os.raise("set_%s(): %s", name, errors)
- end
-
- -- update script?
- scope[name] = {}
- table.insert(scope[name], instance:script())
-
- end
-
- -- register implementation
- self:_api_register_xxx_values(scope_kind, "set", implementation, ...)
-end
-
--- return module: deprecated_interpreter
-return deprecated_interpreter
diff --git a/xmake/core/base/dump.lua b/xmake/core/base/dump.lua
index 80f4e49b1..22c5e32b8 100644
--- a/xmake/core/base/dump.lua
+++ b/xmake/core/base/dump.lua
@@ -196,7 +196,7 @@ function dump._print_udata(value, first_indent, remain_indent, printed_set)
io.write(first_indent)
if not first_level then
- return dump._print_udata_scalar(value)
+ io.write(todisplay._print_udata_scalar(value))
end
local inner_indent = remain_indent .. " "
diff --git a/xmake/core/base/filter.lua b/xmake/core/base/filter.lua
index d7595679c..f0dae3061 100644
--- a/xmake/core/base/filter.lua
+++ b/xmake/core/base/filter.lua
@@ -171,15 +171,21 @@ function filter:handle(value)
value = value:gsub("%%([%$%(%)%%])", function (ch) return escape_table1[ch] end)
-- filter the builtin variables
- return (value:gsub("%$%((.-)%)", function (variable)
-
+ local values = {}
+ local variables = {}
+ value:gsub("%$%((.-)%)", function (variable)
+ table.insert(variables, variable)
+ end)
+ -- we cannot call self:get() in gsub, because it will trigger "attempt to yield a c-call boundary"
+ for _, variable in ipairs(variables) do
-- escape "%$", "%(", "%)", "%%" to "$", "(", ")", "%"
- variable = variable:gsub("[\001\002\003\004]", function (ch) return escape_table2[ch] end)
-
- -- get variable value
- return self:get(variable) or ""
-
- end):gsub("[\001\002\003\004]", function (ch) return escape_table2[ch] end))
+ local name = variable:gsub("[\001\002\003\004]", function (ch) return escape_table2[ch] end)
+ values[variable] = self:get(name) or ""
+ end
+ value = value:gsub("%$%((.-)%)", function (variable)
+ return values[variable]
+ end)
+ return value:gsub("[\001\002\003\004]", function (ch) return escape_table2[ch] end)
end
-- return module: filter
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua
index 2f26e20ce..6f5f0360b 100644
--- a/xmake/core/base/interpreter.lua
+++ b/xmake/core/base/interpreter.lua
@@ -22,13 +22,14 @@
local interpreter = interpreter or {}
-- load modules
-local os = require("base/os")
-local path = require("base/path")
-local table = require("base/table")
-local utils = require("base/utils")
-local string = require("base/string")
-local scopeinfo = require("base/scopeinfo")
-local sandbox = require("sandbox/sandbox")
+local os = require("base/os")
+local path = require("base/path")
+local table = require("base/table")
+local utils = require("base/utils")
+local string = require("base/string")
+local scopeinfo = require("base/scopeinfo")
+local deprecated = require("base/deprecated")
+local sandbox = require("sandbox/sandbox")
-- traceback
function interpreter._traceback(errors)
@@ -160,8 +161,6 @@ end
-- register scope end: scopename_end()
function interpreter:_api_register_scope_end(...)
-
- -- check
assert(self and self._PUBLIC and self._PRIVATE)
-- done
@@ -191,8 +190,6 @@ end
-- register scope api: xxx_apiname()
function interpreter:_api_register_scope_api(scope_kind, action, apifunc, ...)
-
- -- check
assert(self and self._PUBLIC and self._PRIVATE)
assert(apifunc)
@@ -226,8 +223,6 @@ end
-- register api: xxx_values()
function interpreter:_api_register_xxx_values(scope_kind, action, apifunc, ...)
-
- -- check
assert(self and self._PUBLIC and self._PRIVATE)
assert(action and apifunc)
@@ -257,7 +252,7 @@ function interpreter:_api_register_xxx_values(scope_kind, action, apifunc, ...)
assert(scope)
-- set values (set, on, before, after ...)? mark as "override"
- if apiname and (action ~= "add" and action ~= "del") then
+ if apiname and (action ~= "add" and action ~= "del" and action ~= "remove") then
scope["__override_" .. apiname] = true
end
@@ -372,8 +367,6 @@ end
-- get api function within scope
function interpreter:_api_within_scope(scope_kind, apiname)
-
- -- the private
local priv = self._PRIVATE
assert(priv)
@@ -394,8 +387,6 @@ end
-- set api function within scope
function interpreter:_api_within_scope_set(scope_kind, apiname, apifunc)
-
- -- the private
local priv = self._PRIVATE
assert(priv)
@@ -416,8 +407,6 @@ end
-- clear results
function interpreter:_clear()
-
- -- check
assert(self and self._PRIVATE)
-- clear it
@@ -427,8 +416,6 @@ end
-- filter values
function interpreter:_filter(values, level)
-
- -- check
assert(self and values ~= nil)
-- return values directly if no filter
@@ -446,7 +433,7 @@ function interpreter:_filter(values, level)
if table.is_dictionary(values) then
local results = {}
for key, value in pairs(values) do
- key = filter:handle(key)
+ key = (type(key) == "string" and filter:handle(key) or key)
if type(value) == "string" then
results[key] = filter:handle(value)
elseif type(value) == "table" and level < 1 then
@@ -459,13 +446,12 @@ function interpreter:_filter(values, level)
else
-- filter value or arrays
values = table.wrap(values)
- for idx = 1, table.maxn(values) do
-
+ for idx = 1, #values do
local value = values[idx]
if type(value) == "string" then
value = filter:handle(value)
elseif table.is_array(value) then
- for i = 1, table.maxn(value) do
+ for i = 1, #value do
local v = value[i]
if type(v) == "string" then
v = filter:handle(v)
@@ -482,25 +468,30 @@ function interpreter:_filter(values, level)
end
-- handle scope data
-function interpreter:_handle(scope, remove_repeat, enable_filter)
-
- -- check
+function interpreter:_handle(scope, deduplicate, enable_filter)
assert(scope)
-- remove repeat values and unwrap it
local results = {}
for name, values in pairs(scope) do
- -- remove repeat first for each slice with deleted item (__del_xxx)
- if remove_repeat and not table.is_dictionary(values) then
- values = table.unique(values, function (v) return type(v) == "string" and v:startswith("__del_") end)
- end
-
-- filter values
+ --
+ -- @note we need do filter before removing repeat values
+ -- https://github.com/xmake-io/xmake/issues/1732
if enable_filter then
values = self:_filter(values)
end
+ -- remove repeat first for each slice with removed item (__remove_xxx)
+ if deduplicate and not table.is_dictionary(values) then
+ local policy = self:deduplication_policy(name)
+ if policy ~= false then
+ local unique_func = policy == "toleft" and table.reverse_unique or table.unique
+ values = unique_func(values, function (v) return type(v) == "string" and v:startswith("__remove_") end)
+ end
+ end
+
-- unwrap it if be only one
values = table.unwrap(values)
@@ -511,9 +502,7 @@ function interpreter:_handle(scope, remove_repeat, enable_filter)
end
-- make results
-function interpreter:_make(scope_kind, remove_repeat, enable_filter)
-
- -- check
+function interpreter:_make(scope_kind, deduplicate, enable_filter)
assert(self and self._PRIVATE)
-- the scopes
@@ -526,12 +515,12 @@ function interpreter:_make(scope_kind, remove_repeat, enable_filter)
-- get the root scope info of the given scope kind, e.g. root.target
local results = {}
- local scope_opt = {interpreter = self, remove_repeat = remove_repeat, enable_filter = enable_filter}
+ local scope_opt = {interpreter = self, deduplicate = deduplicate, enable_filter = enable_filter}
if scope_kind and scope_kind:startswith("root.") then
local root_scope = scopes._ROOT[scope_kind:sub(6)]
if root_scope then
- results = self:_handle(root_scope, remove_repeat, enable_filter)
+ results = self:_handle(root_scope, deduplicate, enable_filter)
end
return scopeinfo.new(scope_kind, results, scope_opt)
@@ -540,7 +529,7 @@ function interpreter:_make(scope_kind, remove_repeat, enable_filter)
local root_scope = scopes._ROOT["__rootkind"]
if root_scope then
- results = self:_handle(root_scope, remove_repeat, enable_filter)
+ results = self:_handle(root_scope, deduplicate, enable_filter)
end
return scopeinfo.new(scope_kind, results, scope_opt)
@@ -576,7 +565,7 @@ function interpreter:_make(scope_kind, remove_repeat, enable_filter)
end
-- add this scope
- results[scope_name] = scopeinfo.new(scope_kind, self:_handle(scope_values, remove_repeat, enable_filter), scope_opt)
+ results[scope_name] = scopeinfo.new(scope_kind, self:_handle(scope_values, deduplicate, enable_filter), scope_opt)
end
end
end
@@ -694,6 +683,10 @@ function interpreter.new()
instance:api_register(nil, "add_subdirs", interpreter.api_builtin_includes)
instance:api_register(nil, "add_subfiles", interpreter.api_builtin_includes)
instance:api_register(nil, "set_xmakever", interpreter.api_builtin_set_xmakever)
+ instance:api_register(nil, "save_scope", interpreter.api_builtin_save_scope)
+ instance:api_register(nil, "restore_scope",interpreter.api_builtin_restore_scope)
+ instance:api_register(nil, "get_scopekind",interpreter.api_builtin_get_scopekind)
+ instance:api_register(nil, "get_scopename",interpreter.api_builtin_get_scopename)
-- register the builtin modules
for module_name, module in pairs(interpreter._builtin_modules()) do
@@ -709,8 +702,6 @@ end
-- @param opt {on_load_data = function (data) return data end}
--
function interpreter:load(file, opt)
-
- -- check
assert(self and self._PUBLIC and self._PRIVATE and file)
-- load the script
@@ -745,11 +736,11 @@ function interpreter:load(file, opt)
end
-- make results
-function interpreter:make(scope_kind, remove_repeat, enable_filter)
+function interpreter:make(scope_kind, deduplicate, enable_filter)
-- get the results with the given scope
self._PENDING = true
- local ok, results = xpcall(interpreter._make, interpreter._traceback, self, scope_kind, remove_repeat, enable_filter)
+ local ok, results = xpcall(interpreter._make, interpreter._traceback, self, scope_kind, deduplicate, enable_filter)
self._PENDING = false
if not ok then
return nil, results
@@ -807,10 +798,36 @@ function interpreter:rootscope_set(scope_kind)
self._PRIVATE._ROOTSCOPE = scope_kind
end
+-- get the deduplication policy
+function interpreter:deduplication_policy(name)
+ local policies = self._PRIVATE._DEDUPLICATION_POLICIES
+ if name then
+ return policies and policies[name]
+ else
+ return policies
+ end
+end
+
+-- set the deduplication policy
+--
+-- we need to be able to precisely control the direction of deduplication of different types of values.
+-- the default is to de-duplicate from left to right, but like links/syslinks need to be de-duplicated from right to left.
+--
+-- e.g
+--
+-- interp:deduplication_set("defines", "right") -- remove duplicates to the right (default)
+-- interp:deduplication_set("links", "left") -- remove duplicates to the left
+-- interp:deduplication_set("links", false) -- disable deduplication
+--
+-- @see https://github.com/xmake-io/xmake/issues/1903
+--
+function interpreter:deduplication_policy_set(name, policy)
+ self._PRIVATE._DEDUPLICATION_POLICIES = self._PRIVATE._DEDUPLICATION_POLICIES or {}
+ self._PRIVATE._DEDUPLICATION_POLICIES[name] = policy
+end
+
-- get apis
function interpreter:apis(scope_kind)
-
- -- check
assert(self and self._PRIVATE)
-- get apis from the given scope kind
@@ -851,8 +868,6 @@ end
-- }
--
function interpreter:api_register(scope_kind, name, func)
-
- -- check
assert(self and self._PUBLIC and self._PRIVATE)
assert(name and func)
@@ -886,11 +901,7 @@ end
-- register api for builtin
function interpreter:api_register_builtin(name, func)
-
- -- check
assert(self and self._PUBLIC and func)
-
- -- register it
self._PUBLIC[name] = func
end
@@ -936,9 +947,6 @@ end
--
function interpreter:api_register_scope(...)
- -- check
- assert(self)
-
-- define implementation
local implementation = function (self, scopes, scope_kind, scope_name, scope_info)
@@ -1051,6 +1059,9 @@ function interpreter:api_register_set_values(scope_kind, ...)
extra_config = nil
end
+ -- expand values
+ values = table.join(table.unpack(values))
+
-- save values
if #values > 0 then
scope[name] = values
@@ -1088,6 +1099,9 @@ function interpreter:api_register_add_values(scope_kind, ...)
extra_config = nil
end
+ -- expand values
+ values = table.join(table.unpack(values))
+
-- save values
scope[name] = table.join2(scope[name] or {}, values)
@@ -1221,17 +1235,20 @@ end
-- register api for set_dictionary
function interpreter:api_register_set_dictionary(scope_kind, ...)
- -- check
- assert(self)
-
-- define implementation
- local implementation = function (self, scope, name, dict_or_key, value)
+ local implementation = function (self, scope, name, dict_or_key, value, extra_config)
-- check
if type(dict_or_key) == "table" then
scope[name] = dict_or_key
elseif type(dict_or_key) == "string" and value ~= nil then
scope[name] = {[dict_or_key] = value}
+ -- save extra config
+ if extra_config and table.is_dictionary(extra_config) then
+ scope["__extra_" .. name] = scope["__extra_" .. name] or {}
+ local extrascope = scope["__extra_" .. name]
+ extrascope[dict_or_key] = extra_config
+ end
else
-- error
os.raise("set_%s(%s): invalid value type!", name, type(dict))
@@ -1245,18 +1262,22 @@ end
-- register api for add_dictionary
function interpreter:api_register_add_dictionary(scope_kind, ...)
- -- check
- assert(self)
-
-- define implementation
- local implementation = function (self, scope, name, dict_or_key, value)
+ local implementation = function (self, scope, name, dict_or_key, value, extra_config)
-- check
scope[name] = scope[name] or {}
if type(dict_or_key) == "table" then
table.join2(scope[name], dict_or_key)
+ extra_config = value
elseif type(dict_or_key) == "string" and value ~= nil then
scope[name][dict_or_key] = value
+ -- save extra config
+ if extra_config and table.is_dictionary(extra_config) then
+ scope["__extra_" .. name] = scope["__extra_" .. name] or {}
+ local extrascope = scope["__extra_" .. name]
+ extrascope[dict_or_key] = extra_config
+ end
else
-- error
os.raise("add_%s(%s): invalid value type!", name, type(dict))
@@ -1270,9 +1291,6 @@ end
-- register api for set_paths
function interpreter:api_register_set_paths(scope_kind, ...)
- -- check
- assert(self)
-
-- define implementation
local implementation = function (self, scope, name, ...)
@@ -1286,7 +1304,7 @@ function interpreter:api_register_set_paths(scope_kind, ...)
end
-- translate paths
- values = table.join(unpack(values))
+ values = table.join(table.unpack(values))
local paths = self:_api_translate_paths(values, "set_" .. name)
-- save values
@@ -1309,12 +1327,9 @@ function interpreter:api_register_set_paths(scope_kind, ...)
self:_api_register_xxx_values(scope_kind, "set", implementation, ...)
end
--- register api for del_paths
+-- register api for del_paths (deprecated)
function interpreter:api_register_del_paths(scope_kind, ...)
- -- check
- assert(self)
-
-- define implementation
local implementation = function (self, scope, name, ...)
@@ -1322,10 +1337,13 @@ function interpreter:api_register_del_paths(scope_kind, ...)
local values = table.join(...)
local paths = self:_api_translate_paths(values, "del_" .. name)
+ -- it has been marked as deprecated
+ deprecated.add("remove_" .. name .. "(%s)", "del_" .. name .. "(%s)", table.concat(values, ", "), table.concat(values, ", "))
+
-- mark these paths as deleted
local paths_deleted = {}
for _, pathname in ipairs(paths) do
- table.insert(paths_deleted, "__del_" .. pathname)
+ table.insert(paths_deleted, "__remove_" .. pathname)
end
-- save values
@@ -1339,12 +1357,36 @@ function interpreter:api_register_del_paths(scope_kind, ...)
self:_api_register_xxx_values(scope_kind, "del", implementation, ...)
end
+-- register api for remove_paths
+function interpreter:api_register_remove_paths(scope_kind, ...)
+
+ -- define implementation
+ local implementation = function (self, scope, name, ...)
+
+ -- translate paths
+ local values = table.join(...)
+ local paths = self:_api_translate_paths(values, "remove_" .. name)
+
+ -- mark these paths as removed
+ local paths_removed = {}
+ for _, pathname in ipairs(paths) do
+ table.insert(paths_removed, "__remove_" .. pathname)
+ end
+
+ -- save values
+ scope[name] = table.join2(scope[name] or {}, paths_removed)
+
+ -- save api source info, e.g. call api() in sourcefile:linenumber
+ self:_save_sourceinfo_to_scope(scope, name, paths)
+ end
+
+ -- register implementation
+ self:_api_register_xxx_values(scope_kind, "remove", implementation, ...)
+end
+
-- register api for add_paths
function interpreter:api_register_add_paths(scope_kind, ...)
- -- check
- assert(self)
-
-- define implementation
local implementation = function (self, scope, name, ...)
@@ -1358,7 +1400,7 @@ function interpreter:api_register_add_paths(scope_kind, ...)
end
-- translate paths
- values = table.join(unpack(values))
+ values = table.join(table.unpack(values))
local paths = self:_api_translate_paths(values, "add_" .. name)
-- save values
@@ -1458,7 +1500,7 @@ function interpreter:api_define(apis)
-- get function prefix
local prefix = nil
- for _, name in ipairs({"set", "add", "del", "on", "before", "after"}) do
+ for _, name in ipairs({"set", "add", "del", "remove", "on", "before", "after"}) do
if funcname:startswith(name .. "_") then
prefix = name
break
@@ -1520,22 +1562,12 @@ end
-- the builtin api: includes()
function interpreter:api_builtin_includes(...)
-
- -- check
assert(self and self._PRIVATE and self._PRIVATE._ROOTDIR and self._PRIVATE._MTIMES)
-
- -- the current file
local curfile = self._PRIVATE._CURFILE
- assert(curfile)
-
- -- the scopes
local scopes = self._PRIVATE._SCOPES
- assert(scopes)
-
- -- get all subpaths
- local subpaths = table.join(...)
-- find all files
+ local subpaths = table.join(...)
local subpaths_matched = {}
for _, subpath in ipairs(subpaths) do
-- find the given files from the project directory
@@ -1633,64 +1665,79 @@ function interpreter:api_builtin_includes(...)
self._PRIVATE._CURFILE = curfile
end
--- get api function
-function interpreter:api_func(apiname)
-
- -- check
- assert(self and self._PUBLIC and apiname)
-
- -- get api function
- return self._PUBLIC[apiname]
-end
-
--- call api
-function interpreter:api_call(apiname, ...)
-
- -- check
- assert(self and apiname)
-
- -- get api function
- local apifunc = self:api_func(apiname)
- if not apifunc then
- os.raise("call %s() failed, this api not found!", apiname)
- end
-
- -- call api function
- return apifunc(...)
-end
-
+-- the builtin api: save_scope()
-- save the current scope
-function interpreter:scope_save()
-
- -- check
+function interpreter:api_builtin_save_scope()
assert(self and self._PRIVATE)
-- the scopes
local scopes = self._PRIVATE._SCOPES
assert(scopes)
- -- the current scope
+ -- save the current scope
local scope = {}
scope._CURRENT = scopes._CURRENT
scope._CURRENT_KIND = scopes._CURRENT_KIND
-
- -- ok?
- return scope
+ self._PRIVATE._SCOPES_SAVED = self._PRIVATE._SCOPES_SAVED or {}
+ table.insert(self._PRIVATE._SCOPES_SAVED, scope)
end
+-- the builtin api: restore_scope()
-- restore the current scope
-function interpreter:scope_restore(scope)
-
- -- check
- assert(self and self._PRIVATE and scope)
+function interpreter:api_builtin_restore_scope()
+ assert(self and self._PRIVATE)
-- the scopes
local scopes = self._PRIVATE._SCOPES
assert(scopes)
-- restore it
- scopes._CURRENT = scope._CURRENT
- scopes._CURRENT_KIND = scope._CURRENT_KIND
+ local scopes_saved = self._PRIVATE._SCOPES_SAVED
+ if scopes_saved and #scopes_saved > 0 then
+ local scope = scopes_saved[#scopes_saved]
+ if scope then
+ scopes._CURRENT = scope._CURRENT
+ scopes._CURRENT_KIND = scope._CURRENT_KIND
+ table.remove(scopes_saved, #scopes_saved)
+ end
+ end
+end
+
+-- the builtin api: get_scopekind()
+function interpreter:api_builtin_get_scopekind()
+ local scopes = self._PRIVATE._SCOPES
+ return scopes._CURRENT_KIND
+end
+
+-- the builtin api: get_scopename()
+function interpreter:api_builtin_get_scopename()
+ local scopes = self._PRIVATE._SCOPES
+ local scope_kind = scopes._CURRENT_KIND
+ if scope_kind and scopes[scope_kind] then
+ local scope_current = scopes._CURRENT
+ for name, scope in pairs(scopes[scope_kind]) do
+ if scope_current == scope then
+ return name
+ end
+ end
+ end
+end
+
+-- get api function
+function interpreter:api_func(apiname)
+ assert(self and self._PUBLIC and apiname)
+ return self._PUBLIC[apiname]
+end
+
+-- call api
+function interpreter:api_call(apiname, ...)
+ assert(self and apiname)
+
+ local apifunc = self:api_func(apiname)
+ if not apifunc then
+ os.raise("call %s() failed, this api not found!", apiname)
+ end
+ return apifunc(...)
end
-- get current instance in the interpreter modules
@@ -1740,8 +1787,6 @@ function interpreter.instance(script)
-- next
level = level + 1
end
-
- -- ok?
return instance
end
diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua
index e43ae7d52..0b38df42a 100644
--- a/xmake/core/base/json.lua
+++ b/xmake/core/base/json.lua
@@ -22,7 +22,7 @@
local json = json or {}
local cjson = cjson or {}
--- laod modules
+-- load modules
local io = require("base/io")
local utils = require("base/utils")
diff --git a/xmake/core/base/libc.lua b/xmake/core/base/libc.lua
new file mode 100644
index 000000000..9aecb8af5
--- /dev/null
+++ b/xmake/core/base/libc.lua
@@ -0,0 +1,134 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file libc.lua
+--
+
+-- define module: libc
+local libc = libc or {}
+
+-- save original interfaces
+libc._malloc = libc._malloc or libc.malloc
+libc._free = libc._free or libc.free
+libc._memcpy = libc._memcpy or libc.memcpy
+libc._memset = libc._memset or libc.memset
+libc._strndup = libc._strndup or libc.strndup
+libc._dataptr = libc._dataptr or libc.dataptr
+libc._byteof = libc._byteof or libc.byteof
+libc._setbyte = libc._setbyte or libc.setbyte
+
+-- load modules
+local ffi = xmake._LUAJIT and require("ffi")
+
+-- define ffi interfaces
+if ffi then
+ ffi.cdef[[
+ void* malloc(size_t size);
+ void free(void* data);
+ ]]
+end
+
+function libc.malloc(size, opt)
+ if ffi then
+ if opt and opt.gc then
+ return ffi.gc(ffi.cast("unsigned char*", ffi.C.malloc(size)), ffi.C.free)
+ else
+ return ffi.cast("unsigned char*", ffi.C.malloc(size))
+ end
+ else
+ local data, errors = libc._malloc(size)
+ if not data then
+ os.raise(errors)
+ end
+ return data
+ end
+end
+
+function libc.free(data)
+ if ffi then
+ return ffi.C.free(data)
+ else
+ return libc._free(data)
+ end
+end
+
+function libc.memcpy(dst, src, size)
+ if ffi then
+ return ffi.copy(dst, src, size)
+ else
+ return libc._memcpy(dst, src, size)
+ end
+end
+
+function libc.memset(data, ch, size)
+ if ffi then
+ return ffi.fill(data, size, ch)
+ else
+ libc._memset(data, ch, size)
+ end
+end
+
+function libc.strndup(s, n)
+ if ffi then
+ return ffi.string(s, n)
+ else
+ local s, errors = libc._strndup(s, n)
+ if not s then
+ os.raise(errors)
+ end
+ return s
+ end
+end
+
+function libc.byteof(data, offset)
+ if ffi then
+ return data[offset]
+ else
+ return libc._byteof(data, offset)
+ end
+end
+
+function libc.setbyte(data, offset, value)
+ if ffi then
+ data[offset] = value
+ else
+ return libc._setbyte(data, offset, value)
+ end
+end
+
+function libc.dataptr(data, opt)
+ if ffi then
+ if opt and opt.gc then
+ return ffi.gc(ffi.cast("unsigned char*", data), ffi.C.free)
+ else
+ return ffi.cast("unsigned char*", data)
+ end
+ else
+ return type(data) == "number" and data or libc._dataptr(data)
+ end
+end
+
+function libc.ptraddr(data)
+ if ffi then
+ return tonumber(ffi.cast('unsigned long long', data))
+ else
+ return data
+ end
+end
+
+-- return module: libc
+return libc
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index e9f403d92..18b59f61c 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -49,7 +49,7 @@ os.SYSERR_NOT_PERM = 1
os.SYSERR_NOT_FILEDIR = 2
-- copy single file or directory
-function os._cp(src, dst, rootdir)
+function os._cp(src, dst, rootdir, opt)
-- check
assert(src and dst)
@@ -65,7 +65,7 @@ function os._cp(src, dst, rootdir)
end
-- is file?
- if os.isfile(src) then
+ if os.isfile(src) or os.islink(src) then
-- the destination is directory? append the filename
if os.isdir(dst) or path.islastsep(dst) then
@@ -76,9 +76,17 @@ function os._cp(src, dst, rootdir)
end
end
- -- copy file
- if not os.cpfile(src, dst) then
- return false, string.format("cannot copy file %s to %s, %s", src, dst, os.strerror())
+ -- link file if reserve symlink
+ if opt and opt.symlink and os.islink(src) then
+ local reallink = os.readlink(src)
+ if not os.link(reallink, dst) then
+ return false, string.format("cannot link %s(%s) to %s, %s", src, reallink, dst, os.strerror())
+ end
+ else
+ -- copy file
+ if not os.cpfile(src, dst) then
+ return false, string.format("cannot copy file %s to %s, %s", src, dst, os.strerror())
+ end
end
-- is directory?
elseif os.isdir(src) then
@@ -243,7 +251,7 @@ end
-- @see https://github.com/xmake-io/xmake-repo/pull/489
-- https://stackoverflow.com/questions/34491244/environment-variable-is-too-large-on-windows-10
--
-function os._remove_repeat_pathenv(value)
+function os._deduplicate_pathenv(value)
if value and #value > 4096 then
local itemset = {}
local results = {}
@@ -369,7 +377,7 @@ end
-- match directories
--
--- @note only return {} without count to simplify code, e.g. unpack(os.dirs(""))
+-- @note only return {} without count to simplify code, e.g. table.unpack(os.dirs(""))
--
function os.dirs(pattern, callback)
return (os.match(pattern, 'd', callback))
@@ -386,7 +394,7 @@ function os.filedirs(pattern, callback)
end
-- copy files or directories and we can reserve the source directory structure
--- e.g. os.cp("src/**.h", "/tmp/", {rootdir = "src"})
+-- e.g. os.cp("src/**.h", "/tmp/", {rootdir = "src", symlink = true})
function os.cp(srcpath, dstpath, opt)
-- check arguments
@@ -405,10 +413,10 @@ function os.cp(srcpath, dstpath, opt)
-- copy files or directories
local srcpathes = os._match_wildcard_pathes(srcpath)
if type(srcpathes) == "string" then
- return os._cp(srcpathes, dstpath, rootdir)
+ return os._cp(srcpathes, dstpath, rootdir, opt)
else
for _, _srcpath in ipairs(srcpathes) do
- local ok, errors = os._cp(_srcpath, dstpath, rootdir)
+ local ok, errors = os._cp(_srcpath, dstpath, rootdir, opt)
if not ok then
return false, errors
end
@@ -723,7 +731,7 @@ function os.execv(program, argv, opt)
end
-- we try to fix too long value before running process
if type(v) == "string" and #v > 4096 and os.host() == "windows" then
- v = os._remove_repeat_pathenv(v)
+ v = os._deduplicate_pathenv(v)
end
envars[k] = v
end
@@ -753,8 +761,6 @@ function os.execv(program, argv, opt)
-- cannot execute process
return nil, os.strerror()
end
-
- -- ok?
return ok
end
@@ -1229,6 +1235,21 @@ function os.cpuinfo(name)
return require("base/cpu").info(name)
end
+-- get the default parallel jobs number
+function os.default_njob()
+ local njob = math.ceil(os.cpuinfo().ncpu * 3 / 2)
+ if os.host() == "windows" and njob > 128 then
+ njob = 128
+ end
+ if njob > 512 then
+ njob = 512
+ end
+ if njob < 1 then
+ njob = 1
+ end
+ return njob
+end
+
-- read the content of symlink
function os.readlink(symlink)
return os._readlink(path.absolute(symlink))
diff --git a/xmake/core/base/pipe.lua b/xmake/core/base/pipe.lua
index 5f7c46c06..92ad42bc6 100644
--- a/xmake/core/base/pipe.lua
+++ b/xmake/core/base/pipe.lua
@@ -67,7 +67,7 @@ function _instance:write(data, opt)
return -1, errors
end
- -- data is bytes? unpack the raw address
+ -- data is bytes? table.unpack the raw address
local datasize = #data
if type(data) == "table" and data.caddr then
datasize = data:size()
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua
index 70ba07414..f4928a887 100644
--- a/xmake/core/base/scheduler.lua
+++ b/xmake/core/base/scheduler.lua
@@ -31,7 +31,7 @@ local poller = require("base/poller")
local timer = require("base/timer")
local hashset = require("base/hashset")
local coroutine = require("base/coroutine")
-local bit = require("bit")
+local bit = require("base/bit")
-- new a coroutine instance
function _coroutine.new(name, thread)
@@ -302,6 +302,7 @@ function scheduler:_co_groups_resume()
local co_groups = self._CO_GROUPS
if co_groups then
local co_groups_waiting = self._CO_GROUPS_WAITING
+ local co_resumed_list = {}
for name, co_group in pairs(co_groups) do
-- get coroutine and limit in waiting group
@@ -326,10 +327,15 @@ function scheduler:_co_groups_resume()
if count >= limit and co_waiting and co_waiting:is_suspended() then
resumed_count = resumed_count + 1
self._CO_GROUPS_WAITING[name] = nil
- local ok, errors = self:co_resume(co_waiting)
- if not ok then
- return -1, errors
- end
+ table.insert(co_resumed_list, co_waiting)
+ end
+ end
+ end
+ if #co_resumed_list > 0 then
+ for _, co_waiting in ipairs(co_resumed_list) do
+ local ok, errors = self:co_resume(co_waiting)
+ if not ok then
+ return -1, errors
end
end
end
diff --git a/xmake/core/base/scopeinfo.lua b/xmake/core/base/scopeinfo.lua
index 70755e14a..26be325eb 100644
--- a/xmake/core/base/scopeinfo.lua
+++ b/xmake/core/base/scopeinfo.lua
@@ -23,11 +23,12 @@ local scopeinfo = scopeinfo or {}
local _instance = _instance or {}
-- load modules
-local io = require("base/io")
-local os = require("base/os")
-local path = require("base/path")
-local table = require("base/table")
-local utils = require("base/utils")
+local io = require("base/io")
+local os = require("base/os")
+local path = require("base/path")
+local table = require("base/table")
+local utils = require("base/utils")
+local deprecated = require("base/deprecated")
-- new an instance
function _instance.new(kind, info, opt)
@@ -35,8 +36,8 @@ function _instance.new(kind, info, opt)
local instance = table.inherit(_instance)
instance._KIND = kind or "root"
instance._INFO = info
- instance._INTERPRETER = opt.interpreter
- instance._REMOVE_REPEAT = opt.remove_repeat
+ instance._INTERPRETER = opt.interpreter
+ instance._DEDUPLICATE = opt.deduplicate
instance._ENABLE_FILTER = opt.enable_filter
return instance
end
@@ -58,13 +59,17 @@ function _instance:_api_type(name)
end
-- handle the api values
-function _instance:_api_handle(values)
+function _instance:_api_handle(name, values)
local interp = self:interpreter()
if interp then
- -- remove repeat first for each slice with deleted item (__del_xxx)
- if self._REMOVE_REPEAT and not table.is_dictionary(values) then
- values = table.unique(values, function (v) return type(v) == "string" and v:startswith("__del_") end)
+ -- remove repeat first for each slice with deleted item (__remove_xxx)
+ if self._DEDUPLICATE and not table.is_dictionary(values) then
+ local policy = interp:deduplication_policy(name)
+ if policy ~= false then
+ local unique_func = policy == "toleft" and table.reverse_unique or table.unique
+ values = unique_func(values, function (v) return type(v) == "string" and v:startswith("__remove_") end)
+ end
end
-- filter values
@@ -109,10 +114,10 @@ function _instance:_api_set_values(name, ...)
end
-- expand values
- values = table.join(unpack(values))
+ values = table.join(table.unpack(values))
-- handle values
- local handled_values = self:_api_handle(values)
+ local handled_values = self:_api_handle(name, values)
-- save values
if type(handled_values) == "table" and #handled_values == 0 then
@@ -148,10 +153,10 @@ function _instance:_api_add_values(name, ...)
end
-- expand values
- values = table.join(unpack(values))
+ values = table.join(table.unpack(values))
-- save values
- scope[name] = self:_api_handle(table.join2(table.wrap(scope[name]), values))
+ scope[name] = self:_api_handle(name, table.join2(table.wrap(scope[name]), values))
-- save extra config
if extra_config then
@@ -180,7 +185,7 @@ function _instance:_api_set_keyvalues(name, key, ...)
-- save values to "name"
scope[name] = scope[name] or {}
- scope[name][key] = self:_api_handle(values)
+ scope[name][key] = self:_api_handle(name, values)
-- save values to "name.key"
local name_key = name .. "." .. key
@@ -218,9 +223,9 @@ function _instance:_api_add_keyvalues(name, key, ...)
-- save values to "name"
scope[name] = scope[name] or {}
if scope[name][key] == nil then
- scope[name][key] = self:_api_handle(values)
+ scope[name][key] = self:_api_handle(name, values)
else
- scope[name][key] = self:_api_handle(table.join2(table.wrap(scope[name][key]), values))
+ scope[name][key] = self:_api_handle(name, table.join2(table.wrap(scope[name][key]), values))
end
-- save values to "name.key"
@@ -238,7 +243,7 @@ function _instance:_api_add_keyvalues(name, key, ...)
end
-- set the api dictionary to the scope info
-function _instance:_api_set_dictionary(name, dict_or_key, value)
+function _instance:_api_set_dictionary(name, dict_or_key, value, extra_config)
-- get the scope info
local scope = self._INFO
@@ -247,11 +252,17 @@ function _instance:_api_set_dictionary(name, dict_or_key, value)
if type(dict_or_key) == "table" then
local dict = {}
for k, v in pairs(dict_or_key) do
- dict[k] = self:_api_handle(v)
+ dict[k] = self:_api_handle(name, v)
end
scope[name] = dict
elseif type(dict_or_key) == "string" and value ~= nil then
- scope[name] = {[dict_or_key] = self:_api_handle(value)}
+ scope[name] = {[dict_or_key] = self:_api_handle(name, value)}
+ -- save extra config
+ if extra_config and table.is_dictionary(extra_config) then
+ scope["__extra_" .. name] = scope["__extra_" .. name] or {}
+ local extrascope = scope["__extra_" .. name]
+ extrascope[dict_or_key] = extra_config
+ end
else
-- error
os.raise("%s:set(%s, ...): invalid value type!", self:kind(), name, type(dict))
@@ -259,7 +270,7 @@ function _instance:_api_set_dictionary(name, dict_or_key, value)
end
-- add the api dictionary to the scope info
-function _instance:_api_add_dictionary(name, dict_or_key, value)
+function _instance:_api_add_dictionary(name, dict_or_key, value, extra_config)
-- get the scope info
local scope = self._INFO
@@ -269,11 +280,17 @@ function _instance:_api_add_dictionary(name, dict_or_key, value)
if type(dict_or_key) == "table" then
local dict = {}
for k, v in pairs(dict_or_key) do
- dict[k] = self:_api_handle(v)
+ dict[k] = self:_api_handle(name, v)
end
table.join2(scope[name], dict)
elseif type(dict_or_key) == "string" and value ~= nil then
- scope[name][dict_or_key] = self:_api_handle(value)
+ scope[name][dict_or_key] = self:_api_handle(name, value)
+ -- save extra config
+ if extra_config and table.is_dictionary(extra_config) then
+ scope["__extra_" .. name] = scope["__extra_" .. name] or {}
+ local extrascope = scope["__extra_" .. name]
+ extrascope[dict_or_key] = extra_config
+ end
else
-- error
os.raise("%s:add(%s, ...): invalid value type!", self:kind(), name, type(dict))
@@ -299,13 +316,13 @@ function _instance:_api_set_paths(name, ...)
end
-- expand values
- values = table.join(unpack(values))
+ values = table.join(table.unpack(values))
-- translate paths
local paths = interp:_api_translate_paths(values, "set_" .. name, 5)
-- save values
- scope[name] = self:_api_handle(paths)
+ scope[name] = self:_api_handle(name, paths)
-- save extra config
if extra_config then
@@ -339,13 +356,13 @@ function _instance:_api_add_paths(name, ...)
end
-- expand values
- values = table.join(unpack(values))
+ values = table.join(table.unpack(values))
-- translate paths
local paths = interp:_api_translate_paths(values, "add_" .. name, 5)
-- save values
- scope[name] = self:_api_handle(table.join2(table.wrap(scope[name]), paths))
+ scope[name] = self:_api_handle(name, table.join2(table.wrap(scope[name]), paths))
-- save extra config
if extra_config then
@@ -360,7 +377,7 @@ function _instance:_api_add_paths(name, ...)
self:_api_save_sourceinfo_to_scope(scope, name, paths)
end
--- remove the api paths to the scope info
+-- remove the api paths to the scope info (deprecated)
function _instance:_api_del_paths(name, ...)
-- get the scope info
@@ -372,17 +389,48 @@ function _instance:_api_del_paths(name, ...)
-- expand values
values = table.join(...)
+ -- it has been marked as deprecated
+ deprecated.add("remove_" .. name .. "(%s)", "del_" .. name .. "(%s)", table.concat(values, ", "), table.concat(values, ", "))
+
-- translate paths
local paths = interp:_api_translate_paths(values, "del_" .. name, 5)
-- mark these paths as deleted
local paths_deleted = {}
for _, pathname in ipairs(paths) do
- table.insert(paths_deleted, "__del_" .. pathname)
+ table.insert(paths_deleted, "__remove_" .. pathname)
end
-- save values
- scope[name] = self:_api_handle(table.join2(table.wrap(scope[name]), paths_deleted))
+ scope[name] = self:_api_handle(name, table.join2(table.wrap(scope[name]), paths_deleted))
+
+ -- save api source info, e.g. call api() in sourcefile:linenumber
+ self:_api_save_sourceinfo_to_scope(scope, name, paths)
+end
+
+-- remove the api paths to the scope info
+function _instance:_api_remove_paths(name, ...)
+
+ -- get the scope info
+ local scope = self._INFO
+
+ -- get interpreter
+ local interp = self:interpreter()
+
+ -- expand values
+ values = table.join(...)
+
+ -- translate paths
+ local paths = interp:_api_translate_paths(values, "remove_" .. name, 5)
+
+ -- mark these paths as removed
+ local paths_removed = {}
+ for _, pathname in ipairs(paths) do
+ table.insert(paths_removed, "__remove_" .. pathname)
+ end
+
+ -- save values
+ scope[name] = self:_api_handle(name, table.join2(table.wrap(scope[name]), paths_removed))
-- save api source info, e.g. call api() in sourcefile:linenumber
self:_api_save_sourceinfo_to_scope(scope, name, paths)
@@ -439,7 +487,7 @@ function _instance:apival_set(name, ...)
local array = name
for _, dict in ipairs(array) do
for k, v in pairs(dict) do
- self:apival_set(k, unpack(table.wrap(v)))
+ self:apival_set(k, table.unpack(table.wrap(v)))
end
end
@@ -447,7 +495,7 @@ function _instance:apival_set(name, ...)
elseif table.is_dictionary(name) then
local dict = name
for k, v in pairs(dict) do
- self:apival_set(k, unpack(table.wrap(v)))
+ self:apival_set(k, table.unpack(table.wrap(v)))
end
elseif name ~= nil then
os.raise("unknown type(%s) for %s:set(%s, ...)", type(name), self:kind(), name)
@@ -475,7 +523,7 @@ function _instance:apival_add(name, ...)
local array = name
for _, dict in ipairs(array) do
for k, v in pairs(dict) do
- self:apival_add(k, unpack(table.wrap(v)))
+ self:apival_add(k, table.unpack(table.wrap(v)))
end
end
@@ -483,19 +531,19 @@ function _instance:apival_add(name, ...)
elseif table.is_dictionary(name) then
local dict = name
for k, v in pairs(dict) do
- self:apival_add(k, unpack(table.wrap(v)))
+ self:apival_add(k, table.unpack(table.wrap(v)))
end
elseif name ~= nil then
os.raise("unknown type(%s) for %s:add(%s, ...)", type(name), self:kind(), name)
end
end
--- remove the api values to the scope info
+-- remove the api values to the scope info (deprecated)
function _instance:apival_del(name, ...)
if type(name) == "string" then
local api_type = self:_api_type("del_" .. name)
if api_type then
- local del_xxx = self["_api_del_" .. api_type]
+ local del_xxx = self["_api_remove_" .. api_type]
if del_xxx then
del_xxx(self, name, ...)
else
@@ -510,6 +558,26 @@ function _instance:apival_del(name, ...)
end
end
+-- remove the api values to the scope info
+function _instance:apival_remove(name, ...)
+ if type(name) == "string" then
+ local api_type = self:_api_type("remove_" .. name)
+ if api_type then
+ local remove_xxx = self["_api_remove_" .. api_type]
+ if remove_xxx then
+ remove_xxx(self, name, ...)
+ else
+ os.raise("unknown apitype(%s) for %s:remove(%s, ...)", api_type, self:kind(), name)
+ end
+ else
+ os.raise("unknown api(%s) for %s:remove(%s, ...)", name, self:kind(), name)
+ end
+ elseif name ~= nil then
+ -- TODO
+ os.raise("cannot support to remove a dictionary!")
+ end
+end
+
-- get the extra configuration
--
-- e.g.
@@ -578,7 +646,7 @@ end
-- clone a new instance from the current
function _instance:clone()
- return _instance.new(self:kind(), self:info(), {interpreter = self:interpreter(), remove_repeat = self._REMOVE_REPEAT, enable_filter = self._ENABLE_FILTER})
+ return _instance.new(self:kind(), self:info(), {interpreter = self:interpreter(), deduplicate = self._DEDUPLICATE, enable_filter = self._ENABLE_FILTER})
end
-- new a scope instance
diff --git a/xmake/core/base/serialize.lua b/xmake/core/base/serialize.lua
index 99486bf8c..2f8030338 100644
--- a/xmake/core/base/serialize.lua
+++ b/xmake/core/base/serialize.lua
@@ -15,7 +15,7 @@
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
--- @author OpportunityLiu
+-- @author OpportunityLiu, ruki
-- @file serialize.lua
--
@@ -24,6 +24,7 @@ local serialize = serialize or {}
local stub = serialize._stub or {}
serialize._stub = stub
serialize._dump = serialize._dump or string._dump or string.dump
+serialize._BCTAG = xmake._LUAJIT and "\27LJ" or "\27Lua"
-- load modules
local math = require("base/math")
@@ -123,7 +124,8 @@ function serialize._maketable(obj, opt, level, pathsegs, reftab)
local sformat = opt.indentstr and "[%q] = %s" or "[%q]=%s"
local nformat = opt.indentstr and "[%s] = %s" or "[%s]=%s"
local keywords = serialize._keywords()
- for k, v in pairs(serialized) do
+ local makepairs = opt.orderkeys and table.orderpairs or pairs
+ for k, v in makepairs(serialized) do
local format
-- serialize key
if type(k) == "string" then
@@ -169,7 +171,7 @@ function serialize._resolvefunction(root, fenv, bytecode)
if type(bytecode) ~= "string" then
return nil, string.format("invalid bytecode (string expected, got %s)", type(bytecode))
end
- if not bytecode:startswith("\27LJ") then
+ if not bytecode:startswith(serialize._BCTAG) then
return nil, "cannot load incompatible bytecode"
end
@@ -235,7 +237,12 @@ function serialize._make(obj, opt)
-- call make* by type
if type(obj) == "string" then
return serialize._makestring(obj, opt)
- elseif type(obj) == "boolean" or type(obj) == "nil" or type(obj) == "number" then
+ elseif type(obj) == "boolean" or type(obj) == "nil" then
+ return serialize._makedefault(obj, opt)
+ elseif type(obj) == "number" then
+ if math.isnan(obj) then -- fix nan for lua 5.3, -nan(ind)
+ return "nan"
+ end
return serialize._makedefault(obj, opt)
elseif type(obj) == "table" then
return serialize._maketable(obj, opt)
@@ -316,7 +323,7 @@ function serialize.save(obj, opt)
end
-- binary mode
- local func, lerr = loadstring("return " .. result, "=")
+ local func, lerr = load("return " .. result, "=")
if lerr ~= nil then
return nil, lerr
end
@@ -424,7 +431,7 @@ function serialize._load(str)
-- load table as script
local result = nil
- local binary = str:startswith("\27LJ")
+ local binary = str:startswith(serialize._BCTAG)
if not binary then
str = "return " .. str
end
diff --git a/xmake/core/base/socket.lua b/xmake/core/base/socket.lua
index 7269cb504..4e6435c09 100644
--- a/xmake/core/base/socket.lua
+++ b/xmake/core/base/socket.lua
@@ -244,7 +244,7 @@ function _instance:send(data, opt)
return -1, errors
end
- -- data is bytes? unpack the raw address
+ -- data is bytes? table.unpack the raw address
local datasize = #data
if type(data) == "table" and data.caddr then
datasize = data:size()
@@ -442,7 +442,7 @@ function _instance:sendto(data, addr, port, opt)
return -1, string.format("%s: sendto empty address!", self)
end
- -- data is bytes? unpack the raw address
+ -- data is bytes? table.unpack the raw address
if type(data) == "table" and data.caddr then
data = {data = data:caddr(), size = data:size()}
end
diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua
index 0be8cc793..686f36d18 100644
--- a/xmake/core/base/string.lua
+++ b/xmake/core/base/string.lua
@@ -24,7 +24,7 @@ local string = string or {}
-- load modules
local deprecated = require("base/deprecated")
local serialize = require("base/serialize")
-local bit = require("bit")
+local bit = require("base/bit")
-- save original interfaces
string._dump = string._dump or string.dump
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua
index edd0f42fb..2bf776151 100644
--- a/xmake/core/base/table.lua
+++ b/xmake/core/base/table.lua
@@ -21,9 +21,50 @@
-- define module: table
local table = table or {}
--- import jit function
-table.clear = require("table.clear")
-table.new = require("table.new")
+-- clear table
+if not table.clear then
+ if xmake._LUAJIT then
+ table.clear = require("table.clear")
+ else
+ function table.clear(t)
+ for k, v in pairs(t) do
+ t[k] = nil
+ end
+ end
+ end
+end
+
+-- new table
+if not table.new then
+ if xmake._LUAJIT then
+ table.new = require("table.new")
+ else
+ function table.new(narray, nhash)
+ -- TODO
+ return {}
+ end
+ end
+end
+
+-- get array length
+if not table.getn then
+ function table.getn(t)
+ return #t
+ end
+end
+
+-- get array max integer key for lua5.4
+if not table.maxn then
+ function table.maxn(t)
+ local max = 0
+ for k, _ in pairs(t) do
+ if type(k) == "number" and k > max then
+ max = k
+ end
+ end
+ return max
+ end
+end
-- move values of table(a1) to table(a2)
--
@@ -186,13 +227,55 @@ function table.is_dictionary(dict)
return type(dict) == "table" and dict[1] == nil
end
+-- does contain the given values in table?
+-- contains arg1 or arg2 ...
+function table.contains(t, arg1, arg2, ...)
+ local found = false
+ if arg2 == nil then -- only one value
+ if table.is_array(t) then
+ for _, v in ipairs(t) do
+ if v == arg1 then
+ found = true
+ break
+ end
+ end
+ else
+ for _, v in pairs(t) do
+ if v == arg1 then
+ found = true
+ break
+ end
+ end
+ end
+ else
+ local values = {}
+ local args = table.pack(arg1, arg2, ...)
+ for _, arg in ipairs(args) do
+ values[arg] = true
+ end
+ if table.is_array(t) then
+ for _, v in ipairs(t) do
+ if values[v] then
+ found = true
+ break
+ end
+ end
+ else
+ for _, v in pairs(t) do
+ if values[v] then
+ found = true
+ break
+ end
+ end
+ end
+ end
+ return found
+end
+
-- read data from iterator, push them to an array
-- usage: table.to_array(ipairs("a", "b")) -> {{1,"a",n=2},{2,"b",n=2}},2
-- usage: table.to_array(io.lines("file")) -> {"line 1","line 2", ... , "line n"},n
function table.to_array(iterator, state, var)
-
- assert(iterator)
-
local result = {}
local count = 0
while true do
@@ -240,21 +323,17 @@ end
-- remove repeat from the given array
function table.unique(array, barrier)
-
if table.is_array(array) then
if table.getn(array) ~= 1 then
local exists = {}
local unique = {}
for _, v in ipairs(array) do
-
-- exists barrier? clear the current existed items
if barrier and barrier(v) then
exists = {}
end
-
-- add unique item
if not exists[v] then
- -- v will not be nil
exists[v] = true
table.insert(unique, v)
end
@@ -265,24 +344,46 @@ function table.unique(array, barrier)
return array
end
+-- reverse to remove repeat from the given array
+function table.reverse_unique(array, barrier)
+ if table.is_array(array) then
+ if table.getn(array) ~= 1 then
+ local exists = {}
+ local unique = {}
+ local n = #array
+ for i = 1, n do
+ local v = array[n - i + 1]
+ -- exists barrier? clear the current existed items
+ if barrier and barrier(v) then
+ exists = {}
+ end
+ -- add unique item
+ if not exists[v] then
+ exists[v] = true
+ table.insert(unique, 1, v)
+ end
+ end
+ array = unique
+ end
+ end
+ return array
+end
+
-- pack arguments into a table
-- polyfill of lua 5.2, @see https://www.lua.org/manual/5.2/manual.html#pdf-table.pack
function table.pack(...)
return { n = select("#", ...), ... }
end
--- unpack table values
--- polyfill of lua 5.2, @see https://www.lua.org/manual/5.2/manual.html#pdf-table.unpack
-table.unpack = unpack
+-- table.unpack table values
+-- polyfill of lua 5.2, @see https://www.lua.org/manual/5.2/manual.html#pdf-unpack
+table.unpack = table.unpack or unpack
-- get keys of a table
-function table.keys(tab)
-
- assert(tab)
-
+function table.keys(tbl)
local keyset = {}
local n = 0
- for k, _ in pairs(tab) do
+ for k, _ in pairs(tbl) do
n = n + 1
keyset[n] = k
end
@@ -290,20 +391,32 @@ function table.keys(tab)
end
-- get order keys of a table
-function table.orderkeys(tab)
- local keys = table.keys(tab)
+function table.orderkeys(tbl)
+ local keys = table.keys(tbl)
table.sort(keys)
return keys
end
--- get values of a table
-function table.values(tab)
-
- assert(tab)
+-- order key/value iterator
+--
+-- for k, v in table.orderpairs(t) do
+-- TODO
+-- end
+function table.orderpairs(t)
+ local orderkeys = table.orderkeys(t)
+ local i = 1
+ return function (t, k)
+ k = orderkeys[i]
+ i = i + 1
+ return k, t[k]
+ end, t, nil
+end
+-- get values of a table
+function table.values(tbl)
local valueset = {}
local n = 0
- for _, v in pairs(tab) do
+ for _, v in pairs(tbl) do
n = n + 1
valueset[n] = v
end
@@ -311,24 +424,16 @@ function table.values(tab)
end
-- map values to a new table
-function table.map(tab, mapper)
-
- assert(tab)
- assert(mapper)
-
- local newtab = {}
- for k, v in pairs(tab) do
- newtab[k] = mapper(k, v)
+function table.map(tbl, mapper)
+ local newtbl = {}
+ for k, v in pairs(tbl) do
+ newtbl[k] = mapper(k, v)
end
- return newtab
+ return newtbl
end
-- map values to a new array
function table.imap(arr, mapper)
-
- assert(arr)
- assert(mapper)
-
local newarr = {}
for k, v in ipairs(arr) do
table.insert(newarr, mapper(k, v))
@@ -338,9 +443,6 @@ end
-- reverse table values
function table.reverse(arr)
-
- assert(arr)
-
local revarr = {}
local l = #arr
for i = 1, l do
@@ -349,5 +451,83 @@ function table.reverse(arr)
return revarr
end
+-- remove values if predicate is matched
+function table.remove_if(tbl, pred)
+ if table.is_array(tbl) then
+ for i = #tbl, 1, -1 do
+ if pred(i, tbl[i]) then
+ table.remove(tbl, i)
+ end
+ end
+ else
+ for k, v in pairs(tbl) do
+ if pred(k, v) then
+ tbl[k] = nil
+ end
+ end
+ end
+ return tbl
+end
+
+-- return indices or keys for the given value
+function table.find(tbl, value)
+ local result
+ if table.is_array(tbl) then
+ for i, v in ipairs(tbl) do
+ if v == value then
+ result = result or {}
+ table.insert(result, i)
+ end
+ end
+ else
+ for k, v in pairs(tbl) do
+ if v == value then
+ result = result or {}
+ table.insert(result, k)
+ end
+ end
+ end
+ return result
+end
+
+-- return indices or keys if predicate is matched
+function table.find_if(tbl, pred)
+ local result
+ if table.is_array(tbl) then
+ for i, v in ipairs(tbl) do
+ if pred(i, v) then
+ result = result or {}
+ table.insert(result, i)
+ end
+ end
+ else
+ for k, v in pairs(tbl) do
+ if pred(k, v) then
+ result = result or {}
+ table.insert(result, k)
+ end
+ end
+ end
+ return result
+end
+
+-- return first index for the given value
+function table.find_first(tbl, value)
+ for i, v in ipairs(tbl) do
+ if v == value then
+ return i
+ end
+ end
+end
+
+-- return first index if predicate is matched
+function table.find_first_if(tbl, pred)
+ for i, v in ipairs(tbl) do
+ if pred(i, v) then
+ return i
+ end
+ end
+end
+
-- return module: table
return table
diff --git a/xmake/core/base/tty.lua b/xmake/core/base/tty.lua
index 0417f9b8f..a744f12e0 100644
--- a/xmake/core/base/tty.lua
+++ b/xmake/core/base/tty.lua
@@ -24,6 +24,9 @@ local tty = tty or {}
-- load modules
local io = require("base/io")
+-- save metatable and builtin functions
+tty._term_mode = tty._term_mode or tty.term_mode
+
-- @see http://www.termsys.demon.co.uk/vtansi.htm
-- write control characters
@@ -392,5 +395,22 @@ function tty.has_color24()
return has_color24
end
+-- get term mode, e.g. stdin, stdout, stderr
+--
+-- local oldmode = tty.term_mode(stdtype)
+-- local oldmode = tty.term_mode(stdtype, newmode)
+--
+function tty.term_mode(stdtype, newmode)
+ local oldmode = 0
+ if stdtype == "stdin" then
+ oldmode = tty._term_mode(1, newmode)
+ elseif stdtype == "stdout" then
+ oldmode = tty._term_mode(2, newmode)
+ elseif stdtype == "stderr" then
+ oldmode = tty._term_mode(3, newmode)
+ end
+ return oldmode
+end
+
-- return module
return tty
diff --git a/xmake/core/base/xmake.lua b/xmake/core/base/xmake.lua
index 406b85b7e..837742af2 100644
--- a/xmake/core/base/xmake.lua
+++ b/xmake/core/base/xmake.lua
@@ -29,7 +29,7 @@ function xmake.name()
return xmake._NAME or "xmake"
end
--- get xmake version
+-- get xmake version, e.g. v2.5.8+dev.d4cff6e11
function xmake.version()
if xmake._VERSION_CACHE == nil then
xmake._VERSION_CACHE = semver.new(xmake._VERSION) or false
@@ -37,6 +37,11 @@ function xmake.version()
return xmake._VERSION_CACHE or nil
end
+-- get the git branch of xmake version, e.g. build: {"dev", "d4cff6e11"}
+function xmake.branch()
+ return xmake.version():build()[1]
+end
+
-- get the program directory
function xmake.programdir()
return xmake._PROGRAM_DIR
@@ -47,5 +52,10 @@ function xmake.programfile()
return xmake._PROGRAM_FILE
end
+-- use luajit?
+function xmake.luajit()
+ return xmake._LUAJIT
+end
+
-- return module: xmake
return xmake
diff --git a/xmake/core/main.lua b/xmake/core/main.lua
index 4664a1c40..e5feb7d14 100644
--- a/xmake/core/main.lua
+++ b/xmake/core/main.lua
@@ -22,6 +22,7 @@
local main = main or {}
-- load modules
+local env = require("base/compat/env")
local os = require("base/os")
local log = require("base/log")
local path = require("base/path")
@@ -43,7 +44,7 @@ local profiler = require("base/profiler")
-- init the option menu
local menu =
{
- title = "${bright}xmake v" .. _VERSION .. ", A cross-platform build utility based on Lua${clear}"
+ title = "${bright}xmake v" .. _VERSION .. ", A cross-platform build utility based on " .. (xmake._LUAJIT and "LuaJIT" or "Lua") .. "${clear}"
, copyright = "Copyright (C) 2015-present Ruki Wang, ${underline}tboox.org${clear}, ${underline}xmake.io${clear}"
-- the tasks: xmake [task]
@@ -217,7 +218,7 @@ function main.entry()
end
-- load theme
- local theme_inst = theme.load(global.get("theme")) or theme.load("default")
+ local theme_inst = theme.load(os.getenv("XMAKE_THEME") or global.get("theme")) or theme.load("default")
if theme_inst then
colors.theme_set(theme_inst)
end
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 28473c2bf..379d1ddea 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -110,19 +110,25 @@ end
-- get the platform of package
function _instance:plat()
+ if self._PLAT then
+ return self._PLAT
+ end
-- @note we uses os.host() instead of them for the binary package
if self:is_binary() then
return os.subhost()
end
local requireinfo = self:requireinfo()
- if not plat and requireinfo and requireinfo.plat then
+ if requireinfo and requireinfo.plat then
return requireinfo.plat
end
- return self:get("plat") or package._target_plat()
+ return package.targetplat()
end
-- get the architecture of package
function _instance:arch()
+ if self._ARCH then
+ return self._ARCH
+ end
-- @note we uses os.arch() instead of them for the binary package
if self:is_binary() then
return os.subarch()
@@ -130,6 +136,16 @@ function _instance:arch()
return self:targetarch()
end
+-- set the package platform
+function _instance:plat_set(plat)
+ self._PLAT = plat
+end
+
+-- set the package architecture
+function _instance:arch_set(arch)
+ self._ARCH = arch
+end
+
-- get the target os
function _instance:targetos()
local requireinfo = self:requireinfo()
@@ -145,7 +161,7 @@ function _instance:targetarch()
if requireinfo and requireinfo.arch then
return requireinfo.arch
end
- return self:get("arch") or package._target_arch()
+ return package.targetarch()
end
-- get the build mode
@@ -255,12 +271,17 @@ function _instance:artifacts_set(artifacts_info)
if not manifest then
os.raise("package(%s): load manifest.txt failed when installing artifacts!", package:displayname())
end
- local vars = manifest.vars
- if vars then
- for k, v in pairs(vars) do
+ if manifest.vars then
+ for k, v in pairs(manifest.vars) do
package:set(k, v)
end
end
+ if manifest.envs then
+ local envs = self:envs()
+ for k, v in pairs(manifest.envs) do
+ envs[k] = v
+ end
+ end
end)
self._IS_PRECOMPILED = true
end
@@ -456,6 +477,18 @@ function _instance:is_parallelize()
return self:get("parallelize") ~= false
end
+-- is local embed package?
+-- we install directly from the local source code instead of downloading it remotely
+function _instance:is_embed()
+ return self:get("sourcedir") and #self:urls() == 0 and self:script("install")
+end
+
+-- is local package?
+-- we will use local installdir and cachedir in current project
+function _instance:is_local()
+ return self:is_embed() or self:is_thirdparty()
+end
+
-- is debug package? (deprecated)
function _instance:debug()
return self:is_debug()
@@ -463,7 +496,7 @@ end
-- is cross-compilation?
function _instance:is_cross()
- if self:is_plat("windows") and os.host() == "windows" then
+ if self:is_plat("windows", "mingw") and os.host() == "windows" then
-- always false on windows host
return false
end
@@ -509,10 +542,48 @@ function _instance:unlock()
end
end
+-- get the source directory
+function _instance:sourcedir()
+ return self:get("sourcedir")
+end
+
+-- get the build directory
+function _instance:buildir()
+ local buildir = self._BUILDIR
+ if not buildir then
+ if self:is_local() then
+ local name = self:name():lower():gsub("::", "_")
+ local rootdir = path.join(config.buildir({absolute = true}), ".packages", name:sub(1, 1):lower(), name, self:version_str())
+ buildir = path.join(rootdir, "cache", "build_" .. self:buildhash():sub(1, 8))
+ else
+ buildir = "build_" .. self:buildhash():sub(1, 8)
+ end
+ self._BUILDIR = buildir
+ end
+ return buildir
+end
+
-- get the cached directory of this package
function _instance:cachedir()
- local name = self:name():lower():gsub("::", "_")
- return path.join(package.cachedir(), name:sub(1, 1):lower(), name, self:version_str())
+ local cachedir = self._CACHEDIR
+ if not cachedir then
+ cachedir = self:get("cachedir")
+ if not cachedir then
+ local name = self:name():lower():gsub("::", "_")
+ local version_str = self:version_str()
+ if self:is_thirdparty() then
+ -- strip `>= <=`
+ version_str = version_str:gsub("[>=<]", "")
+ end
+ if self:is_local() then
+ cachedir = path.join(config.buildir({absolute = true}), ".packages", name:sub(1, 1):lower(), name, version_str, "cache")
+ else
+ cachedir = path.join(package.cachedir(), name:sub(1, 1):lower(), name, version_str)
+ end
+ end
+ self._CACHEDIR = cachedir
+ end
+ return cachedir
end
-- get the installed directory of this package
@@ -522,9 +593,18 @@ function _instance:installdir(...)
installdir = self:get("installdir")
if not installdir then
local name = self:name():lower():gsub("::", "_")
- installdir = path.join(package.installdir(), name:sub(1, 1):lower(), name)
- if self:version_str() then
- installdir = path.join(installdir, self:version_str())
+ if self:is_local() then
+ installdir = path.join(config.buildir({absolute = true}), ".packages", name:sub(1, 1):lower(), name)
+ else
+ installdir = path.join(package.installdir(), name:sub(1, 1):lower(), name)
+ end
+ local version_str = self:version_str()
+ if version_str then
+ if self:is_thirdparty() then
+ -- strip `>= <=`
+ version_str = version_str:gsub("[>=<]", "")
+ end
+ installdir = path.join(installdir, version_str)
end
installdir = path.join(installdir, self:buildhash())
end
@@ -623,6 +703,7 @@ function _instance:manifest_save()
manifest.repo.name = repo:name()
manifest.repo.url = repo:url()
manifest.repo.branch = repo:branch()
+ manifest.repo.commit = repo:commit()
end
-- save manifest
@@ -676,7 +757,7 @@ function _instance:envs_enter()
end
end
else
- os.addenv(name, unpack(table.wrap(values)))
+ os.addenv(name, table.unpack(table.wrap(values)))
end
end
end
@@ -790,6 +871,22 @@ function _instance:toolconfig(name)
end
end
+-- has the given tool for the current package?
+--
+-- e.g.
+--
+-- if package:has_tool("cc", "clang", "gcc") then
+-- ...
+-- end
+function _instance:has_tool(toolkind, ...)
+ local _, toolname = self:tool(toolkind)
+ for _, v in ipairs(table.join(...)) do
+ if v and toolname:find("^" .. v:gsub("%-", "%%-") .. "$") then
+ return true
+ end
+ end
+end
+
-- get the user private data
function _instance:data(name)
return self._DATA and self._DATA[name] or nil
@@ -850,22 +947,7 @@ function _instance:version_str()
return self._VERSION_STR
end
--- get branch version
-function _instance:branch()
- return self._BRANCH
-end
-
--- get tag version
-function _instance:tag()
- return self._TAG
-end
-
--- is git ref?
-function _instance:gitref()
- return self:branch() or self:tag()
-end
-
--- set the version, source: branches, tags, versions
+-- set the version, source: branch, tag, version
function _instance:version_set(version, source)
-- save the semver version
@@ -875,17 +957,31 @@ function _instance:version_set(version, source)
end
-- save branch and tag
- if source == "branches" then
+ if source == "branch" then
self._BRANCH = version
- elseif source == "tags" then
+ elseif source == "tag" then
self._TAG = version
end
- -- save source and version string
- self._SOURCE = source
+ -- save version string
self._VERSION_STR = version
end
+-- get branch version
+function _instance:branch()
+ return self._BRANCH
+end
+
+-- get tag version
+function _instance:tag()
+ return self._TAG
+end
+
+-- is git ref?
+function _instance:gitref()
+ return self:branch() or self:tag()
+end
+
-- get the require info
function _instance:requireinfo()
return self._REQUIREINFO
@@ -968,6 +1064,9 @@ function _instance:buildhash()
-- We cannot directly deserialize the table, so the result may be different each time
local configs_order = {}
for k, v in pairs(table.wrap(configs)) do
+ if type(v) == "table" then
+ v = string.serialize(v, {strip = true, indent = false, orderkeys = true})
+ end
table.insert(configs_order, k .. "=" .. tostring(v))
end
table.sort(configs_order)
@@ -1119,10 +1218,11 @@ function _instance:_fetch_tool(opt)
if fetchinfo == nil then
self._find_tool = self._find_tool or sandbox_module.import("lib.detect.find_tool", {anonymous = true})
if opt.system then
- local fetchnames = {self:name()}
+ local fetchnames = {}
if not self:is_thirdparty() then
table.join2(fetchnames, self:extsources())
end
+ table.insert(fetchnames, self:name())
for _, fetchname in ipairs(fetchnames) do
fetchinfo = self:find_tool(fetchname, opt)
if fetchinfo then
@@ -1172,13 +1272,18 @@ function _instance:_fetch_library(opt)
fetchinfo.sysincludedirs = nil
end
end
+ if fetchinfo and option.get("verbose") then
+ local reponame = self:repo() and self:repo():name() or ""
+ utils.cprint("checking for %s::%s ... ${color.success}%s %s", reponame, self:name(), self:name(), fetchinfo.version and fetchinfo.version or "")
+ end
end
if fetchinfo == nil then
if opt.system then
- local fetchnames = {self:name()}
+ local fetchnames = {}
if not self:is_thirdparty() then
table.join2(fetchnames, self:extsources())
end
+ table.insert(fetchnames, self:name())
for _, fetchname in ipairs(fetchnames) do
fetchinfo = self:find_package(fetchname, opt)
if fetchinfo then
@@ -1201,6 +1306,8 @@ function _instance:find_tool(name, opt)
opt = opt or {}
self._find_tool = self._find_tool or sandbox_module.import("lib.detect.find_tool", {anonymous = true})
return self._find_tool(name, {cachekey = opt.cachekey or "fetch_package_system",
+ installdir = self:installdir(),
+ version = true, -- we alway check version
require_version = opt.require_version,
norun = opt.norun,
force = opt.force})
@@ -1216,11 +1323,13 @@ function _instance:find_package(name, opt)
end
return self._find_package(name, {
force = opt.force,
+ installdir = self:installdir(),
+ version = true, -- we alway check version
require_version = opt.require_version,
mode = self:mode(),
plat = self:plat(),
arch = self:arch(),
- pkgconfigs = self:configs(),
+ configs = table.join(self:configs(), opt.configs),
buildhash = self:buildhash(), -- for xmake package or 3rd package manager, e.g. go:: ..
cachekey = opt.cachekey or "fetch_package_system",
external = opt.external,
@@ -1341,9 +1450,7 @@ function _instance:fetch_linkdeps()
fetchinfo = table.copy(fetchinfo) -- avoid the cached fetchinfo be modified
local linkdeps = self:linkdeps()
if linkdeps then
- local total = #linkdeps
- for idx, _ in ipairs(linkdeps) do
- local dep = linkdeps[total + 1 - idx]
+ for _, dep in ipairs(linkdeps) do
local depinfo = dep:fetch()
if depinfo then
for name, values in pairs(depinfo) do
@@ -1357,7 +1464,11 @@ function _instance:fetch_linkdeps()
end
if fetchinfo then
for name, values in pairs(fetchinfo) do
- fetchinfo[name] = table.unwrap(table.unique(table.wrap(values)))
+ if name == "links" or name == "syslinks" or name == "frameworks" then
+ fetchinfo[name] = table.unwrap(table.reverse_unique(table.wrap(values)))
+ else
+ fetchinfo[name] = table.unwrap(table.unique(table.wrap(values)))
+ end
end
end
return fetchinfo
@@ -1474,7 +1585,7 @@ end
-- @param funcs the funcs
-- @param opt the argument options, e.g. { includes = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:has_cfuncs(funcs, opt)
opt = opt or {}
@@ -1488,7 +1599,7 @@ end
-- @param funcs the funcs
-- @param opt the argument options, e.g. {includes = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:has_cxxfuncs(funcs, opt)
opt = opt or {}
@@ -1502,7 +1613,7 @@ end
-- @param types the types
-- @param opt the argument options, e.g. { defines = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:has_ctypes(types, opt)
opt = opt or {}
@@ -1516,7 +1627,7 @@ end
-- @param types the types
-- @param opt the argument options, e.g. { defines = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:has_cxxtypes(types, opt)
opt = opt or {}
@@ -1530,7 +1641,7 @@ end
-- @param includes the includes
-- @param opt the argument options, e.g. { defines = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:has_cincludes(includes, opt)
opt = opt or {}
@@ -1544,7 +1655,7 @@ end
-- @param includes the includes
-- @param opt the argument options, e.g. { defines = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:has_cxxincludes(includes, opt)
opt = opt or {}
@@ -1558,7 +1669,7 @@ end
-- @param snippets the snippets
-- @param opt the argument options, e.g. { includes = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:check_csnippets(snippets, opt)
opt = opt or {}
@@ -1572,7 +1683,7 @@ end
-- @param snippets the snippets
-- @param opt the argument options, e.g. { includes = ""}
--
--- @return true or false
+-- @return true or false, errors
--
function _instance:check_cxxsnippets(snippets, opt)
opt = opt or {}
@@ -1588,7 +1699,7 @@ end
-- the current platform is belong to the given platforms?
function package._api_is_plat(interp, ...)
- local plat = package._target_plat()
+ local plat = package.targetplat()
for _, v in ipairs(table.join(...)) do
if v and plat == v then
return true
@@ -1598,7 +1709,7 @@ end
-- the current platform is belong to the given architectures?
function package._api_is_arch(interp, ...)
- local arch = package._target_arch()
+ local arch = package.targetarch()
for _, v in ipairs(table.join(...)) do
if v and arch:find("^" .. v:gsub("%-", "%%-") .. "$") then
return true
@@ -1653,7 +1764,7 @@ function package._project()
end
-- get global target platform of package
-function package._target_plat()
+function package.targetplat()
local plat = package._memcache():get("target_plat")
if plat == nil then
if not plat and package._project() then
@@ -1671,7 +1782,7 @@ function package._target_plat()
end
-- get global target architecture of pacakge
-function package._target_arch()
+function package.targetarch()
local arch = package._memcache():get("target_arch")
if arch == nil then
if not arch and package._project() then
@@ -1698,12 +1809,14 @@ function package.apis()
-- package.set_xxx
"package.set_urls"
, "package.set_kind"
- , "package.set_plat"
- , "package.set_arch"
+ , "package.set_plat" -- deprecated
+ , "package.set_arch" -- deprecated
, "package.set_license"
, "package.set_homepage"
, "package.set_description"
, "package.set_parallelize"
+ , "package.set_sourcedir"
+ , "package.set_cachedir"
, "package.set_installdir"
-- package.add_xxx
, "package.add_deps"
@@ -1795,12 +1908,15 @@ function package.load_from_system(packagename)
-- on install script
local on_install = function (pkg)
- local opt = table.copy(pkg:configs())
+ local opt = {}
+ opt.configs = pkg:configs()
opt.mode = pkg:is_debug() and "debug" or "release"
opt.plat = pkg:plat()
opt.arch = pkg:arch()
opt.require_version = pkg:version_str()
opt.buildhash = pkg:buildhash()
+ opt.cachedir = pkg:cachedir()
+ opt.installdir = pkg:installdir()
import("package.manager.install_package")(pkg:name(), opt)
end
@@ -1828,9 +1944,9 @@ function package.load_from_system(packagename)
if is_thirdparty then
-- add configurations for the 3rd package
- local install_package = sandbox_module.import("package.manager." .. packagename:split("::")[1]:lower() .. ".install_package", {try = true, anonymous = true})
- if install_package and install_package.configurations then
- for name, conf in pairs(install_package.configurations()) do
+ local configurations = sandbox_module.import("package.manager." .. packagename:split("::")[1]:lower() .. ".configurations", {try = true, anonymous = true})
+ if configurations then
+ for name, conf in pairs(configurations()) do
instance:add("configs", name, conf)
end
end
diff --git a/xmake/core/package/repository.lua b/xmake/core/package/repository.lua
index 6485b426f..fd9a275f1 100644
--- a/xmake/core/package/repository.lua
+++ b/xmake/core/package/repository.lua
@@ -74,6 +74,16 @@ function _instance:branch()
return self._BRANCH
end
+-- get the current commit
+function _instance:commit()
+ return self._COMMIT
+end
+
+-- set the commit
+function _instance:commit_set(commit)
+ self._COMMIT = commit
+end
+
-- is global repository?
function _instance:is_global()
return self._IS_GLOBAL
diff --git a/xmake/core/project/config.lua b/xmake/core/project/config.lua
index 31e7d0cb5..d6dbcc962 100644
--- a/xmake/core/project/config.lua
+++ b/xmake/core/project/config.lua
@@ -90,23 +90,20 @@ function config.options()
end
-- get the buildir
-function config.buildir()
+-- we can use `{absolute = true}` to force to get absolute path
+function config.buildir(opt)
-- get the absolute path first
+ opt = opt or {}
local buildir = config.get("buildir") or "build"
if not path.is_absolute(buildir) then
- local rootdir
- if os.isdir(path.join(os.workingdir(), ".xmake")) then
- -- we switch to independent working directory @see https://github.com/xmake-io/xmake/issues/820
- rootdir = os.workingdir()
- else
- rootdir = os.projectdir()
- end
- buildir = path.absolute(buildir, rootdir)
+ buildir = path.absolute(buildir, os.projectdir())
end
-- adjust path for the current directory
- buildir = path.relative(buildir, os.curdir())
+ if not opt.absolute then
+ buildir = path.relative(buildir, os.curdir())
+ end
return buildir
end
@@ -171,9 +168,9 @@ function config.save(filepath, opt)
configs[name] = value
end
end
- return io.save(filepath, configs)
+ return io.save(filepath, configs, {orderkeys = true})
else
- return io.save(filepath, config.options())
+ return io.save(filepath, config.options(), {orderkeys = true})
end
end
diff --git a/xmake/core/project/deprecated/project.lua b/xmake/core/project/deprecated/project.lua
index dceeac9ba..46e06b7be 100644
--- a/xmake/core/project/deprecated/project.lua
+++ b/xmake/core/project/deprecated/project.lua
@@ -31,7 +31,6 @@ local rule = require("project/rule")
local config = require("project/config")
local platform = require("platform/platform")
local deprecated = require("base/deprecated")
-local deprecated_interpreter = require("base/deprecated/interpreter")
-- add_headers for target
function deprecated_project._api_target_add_headers(interp)
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
index 93d25990f..0364b3b47 100644
--- a/xmake/core/project/option.lua
+++ b/xmake/core/project/option.lua
@@ -68,22 +68,23 @@ function _instance:_clear()
option._cache():set(self:name(), nil)
end
--- check option conditions
-function _instance:_do_check()
+-- check snippets
+function _instance:_do_check_cxsnippets(snippets)
-- import check_cxsnippets()
self._check_cxsnippets = self._check_cxsnippets or sandbox_module.import("lib.detect.check_cxsnippets", {anonymous = true})
-- check for c and c++
- local passed = nil
+ local passed = 0
+ local result_output
for _, kind in ipairs({"c", "cxx"}) do
-- get conditions
- local links = self:get("links")
- local snippets = self:get(kind .. "snippets")
- local types = self:get(kind .. "types")
- local funcs = self:get(kind .. "funcs")
- local includes = self:get(kind .. "includes")
+ local links = self:get("links")
+ local snippets = self:get(kind .. "snippets")
+ local types = self:get(kind .. "types")
+ local funcs = self:get(kind .. "funcs")
+ local includes = self:get(kind .. "includes")
-- TODO it is deprecated
local snippet = self:get(kind .. "snippet")
@@ -100,23 +101,98 @@ function _instance:_do_check()
sourcekind = "cc"
end
- -- check it
- local ok, results_or_errors = sandbox.load(self._check_cxsnippets, snippets, {target = self, sourcekind = sourcekind, types = types, funcs = funcs, includes = includes})
- if not ok then
- return false, results_or_errors
+ -- split snippets
+ local snippets_build = {}
+ local snippets_tryrun = {}
+ local snippets_output = {}
+ if snippets then
+ for name, snippet in pairs(snippets) do
+ if self:extraconf(kind .. "snippets", name, "output") then
+ snippets_output[name] = snippet
+ elseif self:extraconf(kind .. "snippets", name, "tryrun") then
+ snippets_tryrun[name] = snippet
+ else
+ snippets_build[name] = snippet
+ end
+ end
+ if #table.keys(snippets_output) > 1 then
+ return false, -1, string.format("option(%s): only support for only one snippet with output!", self:name())
+ end
+ end
+
+ -- check snippets (run with output)
+ if #table.keys(snippets_output) > 0 then
+ local ok, results_or_errors, output = sandbox.load(self._check_cxsnippets, snippets_output, {
+ target = self,
+ sourcekind = sourcekind,
+ types = types,
+ funcs = funcs,
+ includes = includes,
+ tryrun = true, output = true})
+ if not ok then
+ return false, -1, results_or_errors
+ end
+
+ -- passed or no passed?
+ if results_or_errors then
+ passed = 1
+ result_output = output
+ else
+ passed = -1
+ break
+ end
end
- -- passed?
- if results_or_errors then
- passed = true
- else
- passed = false
- break
+ -- check snippets (run only)
+ if passed == 0 and #table.keys(snippets_tryrun) > 0 then
+ local ok, results_or_errors = sandbox.load(self._check_cxsnippets, snippets_tryrun, {
+ target = self,
+ sourcekind = sourcekind,
+ types = types,
+ funcs = funcs,
+ includes = includes,
+ tryrun = true})
+ if not ok then
+ return false, -1, results_or_errors
+ end
+
+ -- passed or no passed?
+ if results_or_errors then
+ passed = 1
+ else
+ passed = -1
+ break
+ end
+ end
+
+ -- check snippets (build only)
+ if passed == 0 or #table.keys(snippets_build) > 0 then
+ local ok, results_or_errors = sandbox.load(self._check_cxsnippets, snippets_build, {
+ target = self,
+ sourcekind = sourcekind,
+ types = types,
+ funcs = funcs,
+ includes = includes})
+ if not ok then
+ return false, -1, results_or_errors
+ end
+
+ -- passed or no passed?
+ if results_or_errors then
+ passed = 1
+ else
+ passed = -1
+ break
+ end
end
end
end
+ return true, passed, result_output
+end
- -- check features
+-- check features
+function _instance:_do_check_features()
+ local passed = 0
local features = self:get("features")
if features then
@@ -127,23 +203,49 @@ function _instance:_do_check()
features = table.wrap(features)
local features_supported = self._core_tool_compiler.has_features(features, {target = self})
if features_supported and #features_supported == #features then
- passed = true
+ passed = 1
end
-- trace
if baseoption.get("verbose") or baseoption.get("diagnosis") then
for _, feature in ipairs(features) do
- utils.cprint("${dim}checking for feature(%s) ... %s", feature, passed and "${color.success}${text.success}" or "${color.nothing}${text.nothing}")
+ utils.cprint("${dim}checking for feature(%s) ... %s", feature, passed > 0 and "${color.success}${text.success}" or "${color.nothing}${text.nothing}")
end
end
end
+ return true, passed
+end
- -- enable this option if be passed
+-- check option conditions
+function _instance:_do_check()
+
+ -- check snippets
+ local ok, passed, errors = self:_do_check_cxsnippets()
+ if not ok then
+ return false, errors
+ end
+
+ -- get snippet output
+ local output
if passed then
- self:enable(true)
+ output = errors
end
- -- ok
+ -- check features
+ if passed == 0 then
+ ok, passed, errors = self:_do_check_features()
+ if not ok then
+ return false, errors
+ end
+ end
+
+ -- enable this option if be passed
+ if passed > 0 then
+ self:enable(true)
+ if output then
+ self:set_value(output)
+ end
+ end
return true
end
@@ -318,6 +420,12 @@ function _instance:del(name, ...)
self:_invalidate()
end
+-- remove the value to the option info (deprecated)
+function _instance:remove(name, ...)
+ self._INFO:apival_remove(name, ...)
+ self:_invalidate()
+end
+
-- get the extra configuration
function _instance:extraconf(name, item, key)
return self._INFO:extraconf(name, item, key)
@@ -432,6 +540,15 @@ function option.interpreter()
-- define apis for language
interp:api_define(language.apis())
+ -- we need to be able to precisely control the direction of deduplication of different types of values.
+ -- the default is to de-duplicate from left to right, but like links/syslinks need to be de-duplicated from right to left.
+ --
+ -- @see https://github.com/xmake-io/xmake/issues/1903
+ --
+ interp:deduplication_policy_set("links", "toleft")
+ interp:deduplication_policy_set("syslinks", "toleft")
+ interp:deduplication_policy_set("frameworks", "toleft")
+
-- register filter handler
interp:filter():register("option", function (variable)
diff --git a/xmake/core/project/policy.lua b/xmake/core/project/policy.lua
index 7040182a2..8491e6883 100644
--- a/xmake/core/project/policy.lua
+++ b/xmake/core/project/policy.lua
@@ -43,8 +43,12 @@ function policy.policies()
["check.target_package_licenses"] = {description = "Enable check the compatibility of target and package licenses.", default = true, type = "boolean"},
-- we can compile the source files for each target in parallel
["build.across_targets_in_parallel"] = {description = "Enable compile the source files for each target in parallel.", default = true, type = "boolean"},
+ -- merge archive intead of linking for all dependent targets
+ ["build.merge_archive"] = {description = "Enable merge archive intead of linking for all dependent targets.", default = false, type = "boolean"},
-- we need enable longpaths when building target or installing package
- ["platform.longpaths"] = {description = "Enable long paths when building target or installing package on windows.", default = false, type = "boolean"}
+ ["platform.longpaths"] = {description = "Enable long paths when building target or installing package on windows.", default = false, type = "boolean"},
+ -- lock required packages
+ ["package.requires_lock"] = {description = "Enable xmake-requires.lock to lock required packages.", default = false, type = "boolean"}
}
policy._POLICIES = policies
end
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 3ff962d7c..3aee363a3 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -215,13 +215,22 @@ end
--
-- orderdeps: c -> b -> a
--
-function project._load_deps(instance, instances, deps, orderdeps)
-
- -- get dep instances
+function project._load_deps(instance, instances, deps, orderdeps, depspath)
for _, dep in ipairs(table.wrap(instance:get("deps"))) do
local depinst = instances[dep]
if depinst then
- project._load_deps(depinst, instances, deps, orderdeps)
+ local depspath_sub
+ if depspath then
+ for idx, name in ipairs(depspath) do
+ if name == dep then
+ local circular_deps = table.slice(depspath, idx)
+ table.insert(circular_deps, dep)
+ os.raise("circular dependency(%s) detected!", table.concat(circular_deps, ", "))
+ end
+ end
+ depspath_sub = table.join(depspath, dep)
+ end
+ project._load_deps(depinst, instances, deps, orderdeps, depspath_sub)
if not deps[dep] then
deps[dep] = depinst
table.insert(orderdeps, depinst)
@@ -231,7 +240,7 @@ function project._load_deps(instance, instances, deps, orderdeps)
end
-- load scope from the project file
-function project._load_scope(scope_kind, remove_repeat, enable_filter)
+function project._load_scope(scope_kind, deduplicate, enable_filter)
-- enter the project directory
local oldir, errors = os.cd(os.projectdir())
@@ -243,7 +252,7 @@ function project._load_scope(scope_kind, remove_repeat, enable_filter)
local interp = project.interpreter()
-- load scope
- local results, errors = interp:make(scope_kind, remove_repeat, enable_filter)
+ local results, errors = interp:make(scope_kind, deduplicate, enable_filter)
if not results then
return nil, errors
end
@@ -316,7 +325,7 @@ function project._load_rules()
for _, instance in pairs(instances) do
instance._DEPS = instance._DEPS or {}
instance._ORDERDEPS = instance._ORDERDEPS or {}
- project._load_deps(instance, instances, instance._DEPS, instance._ORDERDEPS)
+ project._load_deps(instance, instances, instance._DEPS, instance._ORDERDEPS, {instance:name()})
end
return rules
end
@@ -344,29 +353,6 @@ function project._load_toolchains()
return toolchains
end
--- load target
-function project._load_target(t, requires)
-
- -- do before_load() for target and all rules
- local ok, errors = t:_load_before()
- if not ok then
- return false, errors
- end
-
- -- do on_load() for target and all rules
- ok, errors = t:_load()
- if not ok then
- return false, errors
- end
-
- -- do after_load() for target and all rules
- ok, errors = t:_load_after()
- if not ok then
- return false, errors
- end
- return true
-end
-
-- load targets
function project._load_targets()
@@ -400,11 +386,6 @@ function project._load_targets()
-- load and attach target deps, rules and packages
for _, t in pairs(targets) do
- -- load deps
- t._DEPS = t._DEPS or {}
- t._ORDERDEPS = t._ORDERDEPS or {}
- project._load_deps(t, targets, t._DEPS, t._ORDERDEPS)
-
-- load rules from target and language
--
-- e.g.
@@ -449,6 +430,24 @@ function project._load_targets()
return nil, nil, string.format("unknown rule(%s) in target(%s)!", rulename, t:name())
end
end
+
+ -- @note it's deprecated, please use on_load instead of before_load
+ ok, errors = t:_load_before()
+ if not ok then
+ return nil, nil, errors
+ end
+
+ -- we need call on_load() before building deps/rules,
+ -- so we can use `target:add("deps", "xxx")` to add deps in on_load
+ ok, errors = t:_load()
+ if not ok then
+ return nil, nil, errors
+ end
+
+ -- load deps
+ t._DEPS = t._DEPS or {}
+ t._ORDERDEPS = t._ORDERDEPS or {}
+ project._load_deps(t, targets, t._DEPS, t._ORDERDEPS, {t:name()})
end
-- sort targets for all deps
@@ -458,19 +457,13 @@ function project._load_targets()
project._sort_targets(targets, ordertargets, targetrefs, t)
end
- -- do load for each target
- local ok = false
+ -- do after_load() for targets
for _, t in ipairs(ordertargets) do
- ok, errors = project._load_target(t, requires)
+ ok, errors = t:_load_after()
if not ok then
- break
+ return nil, nil, errors
end
end
-
- -- do load failed?
- if not ok then
- return nil, nil, errors
- end
return targets, ordertargets
end
@@ -547,10 +540,8 @@ function project._load_options(disable_filter)
for _, opt in pairs(options) do
opt._DEPS = opt._DEPS or {}
opt._ORDERDEPS = opt._ORDERDEPS or {}
- project._load_deps(opt, options, opt._DEPS, opt._ORDERDEPS)
+ project._load_deps(opt, options, opt._DEPS, opt._ORDERDEPS, {opt:name()})
end
-
- -- ok?
return options
end
@@ -736,6 +727,15 @@ function project.interpreter()
-- define apis for project
interp:api_define(project.apis())
+ -- we need to be able to precisely control the direction of deduplication of different types of values.
+ -- the default is to de-duplicate from left to right, but like links/syslinks need to be de-duplicated from right to left.
+ --
+ -- @see https://github.com/xmake-io/xmake/issues/1903
+ --
+ interp:deduplication_policy_set("links", "toleft")
+ interp:deduplication_policy_set("syslinks", "toleft")
+ interp:deduplication_policy_set("frameworks", "toleft")
+
-- register api: deprecated
deprecated_project.api_register(interp)
@@ -1014,6 +1014,16 @@ function project.requireconfs_str()
return requireconfs_str, requireconfs_extra
end
+-- get requires lockfile
+function project.requireslock()
+ return path.join(project.directory(), "xmake-requires.lock")
+end
+
+-- get the format version of requires lockfile
+function project.requireslock_version()
+ return "1.0"
+end
+
-- get the given rule
function project.rule(name)
return project.rules()[name]
@@ -1082,7 +1092,15 @@ end
-- get the mtimes
function project.mtimes()
- return project.interpreter():mtimes()
+ local mtimes = project._MTIMES
+ if not mtimes then
+ mtimes = project.interpreter():mtimes()
+ for _, rcfile in ipairs(project.rcfiles()) do
+ mtimes[rcfile] = os.mtime(rcfile)
+ end
+ project._MTIMES = mtimes
+ end
+ return mtimes
end
-- get the project menu
diff --git a/xmake/core/project/rule.lua b/xmake/core/project/rule.lua
index 87a082888..c155a813f 100644
--- a/xmake/core/project/rule.lua
+++ b/xmake/core/project/rule.lua
@@ -174,6 +174,7 @@ function rule.apis()
, "rule.on_package"
, "rule.on_install"
, "rule.on_uninstall"
+ , "rule.on_linkcmd"
, "rule.on_buildcmd"
, "rule.on_buildcmd_file"
, "rule.on_buildcmd_files"
@@ -188,6 +189,7 @@ function rule.apis()
, "rule.before_package"
, "rule.before_install"
, "rule.before_uninstall"
+ , "rule.before_linkcmd"
, "rule.before_buildcmd"
, "rule.before_buildcmd_file"
, "rule.before_buildcmd_files"
@@ -202,6 +204,7 @@ function rule.apis()
, "rule.after_package"
, "rule.after_install"
, "rule.after_uninstall"
+ , "rule.after_linkcmd"
, "rule.after_buildcmd"
, "rule.after_buildcmd_file"
, "rule.after_buildcmd_files"
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 3eed0cdad..be787619b 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -23,7 +23,7 @@ local target = target or {}
local _instance = _instance or {}
-- load modules
-local bit = require("bit")
+local bit = require("base/bit")
local os = require("base/os")
local path = require("base/path")
local utils = require("base/utils")
@@ -82,6 +82,11 @@ function _instance:_load_rule(ruleinst, suffix)
else
cache[key] = {true}
end
+
+ -- before_load has been deprecated
+ if on_load and suffix == "before" then
+ deprecated.add(ruleinst:name() .. ".on_load", ruleinst:name() .. ".before_load")
+ end
end
-- save cache
@@ -105,17 +110,6 @@ function _instance:_load_rules(suffix)
return true
end
--- do before_load target and rules
-function _instance:_load_before()
-
- -- do before_load with target rules
- local ok, errors = self:_load_rules("before")
- if not ok then
- return false, errors
- end
- return true
-end
-
-- do load target and rules
function _instance:_load()
@@ -133,6 +127,19 @@ function _instance:_load()
return false, errors
end
end
+
+ -- mark as loaded
+ self._LOADED = true
+ return true
+end
+
+-- do before_load for rules
+-- @note it's deprecated, please use on_load instead of before_load
+function _instance:_load_before()
+ local ok, errors = self:_load_rules("before")
+ if not ok then
+ return false, errors
+ end
return true
end
@@ -142,6 +149,15 @@ function _instance:_load_after()
-- enter the environments of the target packages
local oldenvs = os.addenvs(self:pkgenvs())
+ -- do load for target
+ local after_load = self:script("load_after")
+ if after_load then
+ local ok, errors = sandbox.load(after_load, self)
+ if not ok then
+ return false, errors
+ end
+ end
+
-- do after_load with target rules
local ok, errors = self:_load_rules("after")
if not ok then
@@ -150,6 +166,7 @@ function _instance:_load_after()
-- leave the environments of the target packages
os.setenvs(oldenvs)
+ self._LOADED_AFTER = true
return true
end
@@ -257,6 +274,11 @@ function _instance:_invalidate(name)
end
end
+-- is loaded?
+function _instance:_is_loaded()
+ return self._LOADED
+end
+
-- get the target info
--
-- e.g.
@@ -371,17 +393,28 @@ function _instance:add(name, ...)
self:_invalidate(name)
end
--- remove the value to the target info
+-- remove the value to the target info (deprecated)
function _instance:del(name, ...)
self._INFO:apival_del(name, ...)
self:_invalidate(name)
end
+-- remove the value to the target info
+function _instance:remove(name, ...)
+ self._INFO:apival_remove(name, ...)
+ self:_invalidate(name)
+end
+
-- get the extra configuration
function _instance:extraconf(name, item, key)
return self._INFO:extraconf(name, item, key)
end
+-- set the extra configuration
+function _instance:extraconf_set(name, item, key, value)
+ self._INFO:extraconf_set(name, item, key, value)
+end
+
-- get user private data
function _instance:data(name)
return self._DATA and self._DATA[name]
@@ -566,21 +599,35 @@ function _instance:basename()
return self:get("basename") or self:name()
end
--- get the target linker
-function _instance:linker()
-
- -- get it from cache first
- if self._LINKER then
- return self._LINKER
+-- get the target compiler
+function _instance:compiler(sourcekind)
+ local compilerinst = self:_memcache():get("compiler")
+ if not compilerinst then
+ if not sourcekind then
+ os.raise("please pass sourcekind to the first argument of target:compiler(), e.g. cc, cxx, as")
+ end
+ local instance, errors = compiler.load(sourcekind, self)
+ if not instance then
+ os.raise(errors)
+ end
+ compilerinst = instance
+ self:_memcache():set("compiler", compilerinst)
end
+ return compilerinst
+end
- -- get the linker instance
- local instance, errors = linker.load(self:kind(), self:sourcekinds(), self)
- if not instance then
- os.raise(errors)
+-- get the target linker
+function _instance:linker()
+ local linkerinst = self:_memcache():get("linker")
+ if not linkerinst then
+ local instance, errors = linker.load(self:kind(), self:sourcekinds(), self)
+ if not instance then
+ os.raise(errors)
+ end
+ linkerinst = instance
+ self:_memcache():set("linker", linkerinst)
end
- self._LINKER = instance
- return instance
+ return linkerinst
end
-- make linking command for this target
@@ -608,11 +655,17 @@ end
-- get target deps
function _instance:deps()
+ if not self:_is_loaded() then
+ os.raise("please call target:deps() or target:dep() in after_load()!")
+ end
return self._DEPS
end
-- get target ordered deps
function _instance:orderdeps()
+ if not self:_is_loaded() then
+ os.raise("please call target:orderdeps() in after_load()!")
+ end
return self._ORDERDEPS
end
@@ -654,9 +707,19 @@ function _instance:is_static()
return self:kind() == "static"
end
+-- is object files target?
+function _instance:is_object()
+ return self:kind() == "object"
+end
+
+-- is headeronly target?
+function _instance:is_headeronly()
+ return self:kind() == "headeronly"
+end
+
-- is library target?
function _instance:is_library()
- return self:is_static() or self:is_shared()
+ return self:is_static() or self:is_shared() or self:is_headeronly()
end
-- is default target?
@@ -707,7 +770,7 @@ function _instance:orderopts(opt)
-- load options if be enabled
orderopts = {}
- for _, name in ipairs(table.wrap(self:get("options"))) do
+ for _, name in ipairs(table.wrap(self:get("options", opt))) do
local opt_ = nil
if config.get(name) then opt_ = option.load(name) end
if opt_ then
@@ -716,7 +779,7 @@ function _instance:orderopts(opt)
end
-- load options from packages if no require info, be compatible with the option package in (*.pkg)
- for _, name in ipairs(table.wrap(self:get("packages"))) do
+ for _, name in ipairs(table.wrap(self:get("packages", opt))) do
if not project_package.load(name) then
local opt_ = nil
if config.get(name) then opt_ = option.load(name) end
@@ -989,13 +1052,13 @@ end
-- get the target file name
function _instance:filename()
- -- only compile objects? no target file
- local targetkind = self:kind()
- if targetkind == "object" then
+ -- no target file?
+ if self:is_object() or self:is_phony() or self:is_headeronly() then
return
end
-- make the target file name and attempt to use the format of linker first
+ local targetkind = self:targetkind()
local filename = self:get("filename")
if not filename then
local prefixname = self:get("prefixname")
@@ -1005,8 +1068,7 @@ function _instance:filename()
plat = self:plat(), arch = self:arch(),
prefixname = prefixname,
suffixname = suffixname,
- extension = extension,
- format = self:linker():format(targetkind)})
+ extension = extension})
end
return filename
end
@@ -1116,11 +1178,15 @@ function _instance:filerules(sourcefile)
if not key2rules then
key2rules = {}
for _, r in pairs(table.wrap(self:rules())) do
- for _, sourcekind in ipairs(table.wrap(r:get("sourcekinds"))) do
+ -- we can also get sourcekinds from add_rules("xxx", {sourcekinds = "cxx"})
+ local rule_sourcekinds = self:extraconf("rules", r:name(), "sourcekinds") or r:get("sourcekinds")
+ for _, sourcekind in ipairs(table.wrap(rule_sourcekinds)) do
key2rules[sourcekind] = key2rules[sourcekind] or {}
table.insert(key2rules[sourcekind], r)
end
- for _, extension in ipairs(table.wrap(r:get("extensions"))) do
+ -- we can also get extensions from add_rules("xxx", {extensions = ".cpp"})
+ local rule_extensions = self:extraconf("rules", r:name(), "extensions") or r:get("extensions")
+ for _, extension in ipairs(table.wrap(rule_extensions)) do
extension = extension:lower()
key2rules[extension] = key2rules[extension] or {}
table.insert(key2rules[extension], r)
@@ -1130,13 +1196,26 @@ function _instance:filerules(sourcefile)
end
-- get target rules from the given sourcekind or extension
+ --
+ -- @note we prefer to use rules with extension because we need to be able to
+ -- override the language code rules set by set_sourcekinds
+ --
+ -- e.g. set_extensions(".bpf.c") will override c++ rules
+ --
+ local rules_override = {}
local filename = path.filename(sourcefile):lower()
for _, r in ipairs(table.wrap(key2rules[path.extension(filename, 2)] or
key2rules[path.extension(filename)] or
key2rules[self:sourcekind_of(filename)])) do
- table.insert(rules, r)
+ if self:extraconf("rules", r:name(), "override") then
+ table.insert(rules_override, r)
+ else
+ table.insert(rules, r)
+ end
end
- return rules
+
+ -- we will use overrided rules first, e.g. add_rules("xxx", {override = true})
+ return #rules_override > 0 and rules_override or rules
end
-- get the config info of the given source file
@@ -1150,22 +1229,22 @@ function _instance:fileconfig(sourcefile)
-- match source files
local results = os.match(filepath)
- if #results == 0 then
+ if #results == 0 and not fileconfig.always_added then
local sourceinfo = (self:get("__sourceinfo_files") or {})[filepath] or {}
utils.warning("cannot match %s(%s).add_files(\"%s\") at %s:%d", self:type(), self:name(), filepath, sourceinfo.file or "", sourceinfo.line or -1)
end
-- process source files
for _, file in ipairs(results) do
-
- -- convert to the relative path
if path.is_absolute(file) then
file = path.relative(file, os.projectdir())
end
-
- -- save it
filesconfig[file] = fileconfig
end
+ -- we also need support always_added, @see https://github.com/xmake-io/xmake/issues/1634
+ if #results == 0 and fileconfig.always_added then
+ filesconfig[filepath] = fileconfig
+ end
end
self._FILESCONFIG = filesconfig
end
@@ -1176,14 +1255,8 @@ end
-- set the config info to the given source file
function _instance:fileconfig_set(sourcefile, info)
-
- -- get files config
local filesconfig = self._FILESCONFIG or {}
-
- -- set config info
filesconfig[sourcefile] = info
-
- -- update files config
self._FILESCONFIG = filesconfig
end
@@ -1205,24 +1278,25 @@ function _instance:sourcefiles()
local i = 1
local count = 0
local sourcefiles = {}
- local sourcefiles_deleted = {}
+ local sourcefiles_removed = {}
local sourcefiles_inserted = {}
- local deleted_count = 0
+ local removed_count = 0
local targetcache = memcache.cache("core.project.target")
for _, file in ipairs(table.wrap(files)) do
- -- mark as deleted files?
- local deleted = false
- if file:startswith("__del_") then
- file = file:sub(7)
- deleted = true
+ -- mark as removed files?
+ local removed = false
+ local prefix = "__remove_"
+ if file:startswith(prefix) then
+ file = file:sub(#prefix + 1)
+ removed = true
end
-- find source files and try to cache the matching results of os.match across targets
-- @see https://github.com/xmake-io/xmake/issues/1353
local results = targetcache:get2("sourcefiles", file)
if not results then
- if deleted then
+ if removed then
results = {file}
else
results = os.files(file)
@@ -1249,7 +1323,7 @@ function _instance:sourcefiles()
end
if #results == 0 then
local sourceinfo = (self:get("__sourceinfo_files") or {})[file] or {}
- utils.warning("cannot match %s(%s).%s_files(\"%s\") at %s:%d", self:type(), self:name(), (deleted and "del" or "add"), file, sourceinfo.file or "", sourceinfo.line or -1)
+ utils.warning("cannot match %s(%s).%s_files(\"%s\") at %s:%d", self:type(), self:name(), (removed and "remove" or "add"), file, sourceinfo.file or "", sourceinfo.line or -1)
end
-- process source files
@@ -1260,10 +1334,10 @@ function _instance:sourcefiles()
sourcefile = path.relative(sourcefile, os.projectdir())
end
- -- add or delete it
- if deleted then
- deleted_count = deleted_count + 1
- table.insert(sourcefiles_deleted, sourcefile)
+ -- add or remove it
+ if removed then
+ removed_count = removed_count + 1
+ table.insert(sourcefiles_removed, sourcefile)
elseif not sourcefiles_inserted[sourcefile] then
table.insert(sourcefiles, sourcefile)
sourcefiles_inserted[sourcefile] = true
@@ -1271,21 +1345,20 @@ function _instance:sourcefiles()
end
end
- -- remove all deleted source files
- if deleted_count > 0 then
- for i = #sourcefiles, 1, -1 do
- local sourcefile = sourcefiles[i]
- for _, deletefile in ipairs(sourcefiles_deleted) do
- local pattern = path.translate(deletefile:gsub("|.*$", ""))
+ -- remove all source files which need be removed
+ if removed_count > 0 then
+ table.remove_if(sourcefiles, function (i, sourcefile)
+ for _, removed_file in ipairs(sourcefiles_removed) do
+ local pattern = path.translate(removed_file:gsub("|.*$", ""))
if pattern:sub(1, 2):find('%.[/\\]') then
pattern = pattern:sub(3)
end
pattern = path.pattern(pattern)
if sourcefile:match(pattern) then
- table.remove(sourcefiles, i)
+ return true
end
end
- end
+ end)
end
self._SOURCEFILES = sourcefiles
@@ -1323,20 +1396,20 @@ function _instance:objectfiles()
-- some object files may be repeat and appear link errors if multi-batches exists, so we need remove all repeat object files
-- e.g. add_files("src/*.c", {rules = {"rule1", "rule2"}})
- local remove_repeat = batchcount > 1
+ local deduplicate = batchcount > 1
-- get object files from all dependent targets (object kind)
if self:orderdeps() then
for _, dep in ipairs(self:orderdeps()) do
if dep:kind() == "object" then
table.join2(objectfiles, dep:objectfiles())
- remove_repeat = true
+ deduplicate = true
end
end
end
-- remove repeat object files
- if remove_repeat then
+ if deduplicate then
objectfiles = table.unique(objectfiles)
end
@@ -1380,58 +1453,78 @@ function _instance:headerfiles(outputdir, only_deprecated)
-- get the source paths and destinate paths
local srcheaders = {}
local dstheaders = {}
+ local srcheaders_removed = {}
+ local removed_count = 0
for _, header in ipairs(table.wrap(headers)) do
+ -- mark as removed files?
+ local removed = false
+ local prefix = "__remove_"
+ if header:startswith(prefix) then
+ header = header:sub(#prefix + 1)
+ removed = true
+ end
+
-- get the root directory
local rootdir, count = header:gsub("|.*$", ""):gsub("%(.*%)$", "")
if count == 0 then
rootdir = nil
end
- -- remove '(' and ')'
+ -- remove '(' and ')' first
local srcpaths = header:gsub("[%(%)]", "")
if srcpaths then
-- get the source paths
srcpaths = os.match(srcpaths)
if srcpaths then
+ if removed then
+ removed_count = removed_count + #srcpaths
+ table.join2(srcheaders_removed, srcpaths)
+ else
+ -- add the source headers
+ table.join2(srcheaders, srcpaths)
- -- add the source headers
- table.join2(srcheaders, srcpaths)
-
- -- get the destinate directories if the install directory exists
- if headerdir then
-
- -- get the prefix directory
- local prefixdir = (extrainfo[header] or {}).prefixdir
-
- -- add the destinate headers
- for _, srcpath in ipairs(srcpaths) do
-
- -- get the destinate directory
- local dstdir = headerdir
- if prefixdir then
- dstdir = path.join(dstdir, prefixdir)
+ -- get the destinate directories if the install directory exists
+ if headerdir then
+ local prefixdir = (extrainfo[header] or {}).prefixdir
+ for _, srcpath in ipairs(srcpaths) do
+ local dstdir = headerdir
+ if prefixdir then
+ dstdir = path.join(dstdir, prefixdir)
+ end
+ local dstheader = nil
+ if rootdir then
+ dstheader = path.absolute(path.relative(srcpath, rootdir), dstdir)
+ else
+ dstheader = path.join(dstdir, path.filename(srcpath))
+ end
+ table.insert(dstheaders, dstheader)
end
-
- -- the destinate header
- local dstheader = nil
- if rootdir then
- dstheader = path.absolute(path.relative(srcpath, rootdir), dstdir)
- else
- dstheader = path.join(dstdir, path.filename(srcpath))
- end
- assert(dstheader)
-
- -- add it
- table.insert(dstheaders, dstheader)
end
end
end
end
end
- -- ok?
+ -- remove all header files which need be removed
+ if removed_count > 0 then
+ table.remove_if(srcheaders, function (i, srcheader)
+ for _, removed_file in ipairs(srcheaders_removed) do
+ local pattern = path.translate(removed_file:gsub("|.*$", ""))
+ if pattern:sub(1, 2):find('%.[/\\]') then
+ pattern = pattern:sub(3)
+ end
+ pattern = path.pattern(pattern)
+ if srcheader:match(pattern) then
+ if i <= #dstheaders then
+ table.remove(dstheaders, i)
+ end
+ return true
+ end
+ end
+ end)
+ end
return srcheaders, dstheaders
end
@@ -1560,12 +1653,21 @@ function _instance:sourcekinds()
local sourcekinds = self._SOURCEKINDS
if not sourcekinds then
sourcekinds = {}
- for _, sourcefile in pairs(self:sourcefiles()) do
- local sourcekind = self:sourcekind_of(sourcefile)
+ for _, sourcebatch in pairs(self:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
if sourcekind then
table.insert(sourcekinds, sourcekind)
end
end
+ -- if the source file is added dynamically, we may not be able to get the sourcekinds,
+ -- so we can only continue to get it from the rule
+ -- https://github.com/xmake-io/xmake/issues/1622#issuecomment-927726697
+ for _, ruleinst in ipairs(self:orderules()) do
+ local rule_sourcekinds = ruleinst:get("sourcekinds")
+ if rule_sourcekinds then
+ table.insert(sourcekinds, rule_sourcekinds)
+ end
+ end
sourcekinds = table.unique(sourcekinds)
self._SOURCEKINDS = sourcekinds
end
@@ -1630,11 +1732,7 @@ function _instance:sourcebatches()
end
end
end
-
- -- cache it
self._SOURCEBATCHES = sourcebatches
-
- -- ok?
return sourcebatches, modified
end
@@ -1848,6 +1946,10 @@ end
-- get the program and name of the given tool kind
function _instance:tool(toolkind)
+ -- we cannot get tool in on_load, because target:toolchains() has been not checked in configuration stage.
+ if not self._LOADED_AFTER then
+ os.raise("we cannot get tool(%s) before target(%s) is loaded, maybe it is called on_load(), please call it in on_config().", toolkind, self:name())
+ end
return toolchain.tool(self:toolchains(), toolkind, {cachekey = "target_" .. self:name(), plat = self:plat(), arch = self:arch(),
before_get = function()
-- get program from set_toolchain/set_tools (deprecated)
@@ -1883,6 +1985,24 @@ function _instance:toolconfig(name)
end})
end
+-- has the given tool for the current target?
+--
+-- e.g.
+--
+-- if target:has_tool("cc", "clang", "gcc") then
+-- ...
+-- end
+function _instance:has_tool(toolkind, ...)
+ local _, toolname = self:tool(toolkind)
+ if toolname then
+ for _, v in ipairs(table.join(...)) do
+ if v and toolname:find("^" .. v:gsub("%-", "%%-") .. "$") then
+ return true
+ end
+ end
+ end
+end
+
-- get target apis
function target.apis()
@@ -1951,8 +2071,11 @@ function target.apis()
, "target.add_cleanfiles"
, "target.add_configfiles"
, "target.add_installfiles"
- -- target.del_xxx
+ -- target.del_xxx (deprecated)
, "target.del_files"
+ -- target.remove_xxx
+ , "target.remove_files"
+ , "target.remove_headerfiles"
}
, dictionary =
{
@@ -1986,6 +2109,7 @@ function target.apis()
, "target.before_uninstall"
-- target.after_xxx
, "target.after_run"
+ , "target.after_load"
, "target.after_link"
, "target.after_build"
, "target.after_build_file"
@@ -2007,7 +2131,7 @@ function target.filename(targetname, targetkind, opt)
-- make filename by format
local filename = targetname
- local format = opt.format or platform.format(targetkind, opt.plat, opt.arch)
+ local format = opt.format or platform.format(targetkind, opt.plat, opt.arch) or "$(name)"
if format then
local splitinfo = format:split("$(name)", {plain = true, strict = true})
local prefixname = splitinfo[1] or ""
@@ -2033,18 +2157,23 @@ function target.filename(targetname, targetkind, opt)
end
-- get the link name of the target file
-function target.linkname(filename)
- local linkname, count = filename:gsub(target.filename("__pattern__", "static"):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
- if count == 0 then
- linkname, count = filename:gsub(target.filename("__pattern__", "shared"):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
+function target.linkname(filename, opt)
+ -- for implib/mingw, e.g. libxxx.dll.a
+ opt = opt or {}
+ if filename:startswith("lib") and filename:endswith(".dll.a") then
+ return filename:sub(4, #filename - 6)
+ end
+ -- for macOS, libxxx.tbd
+ if filename:startswith("lib") and filename:endswith(".tbd") then
+ return filename:sub(4, #filename - 4)
end
+ local linkname, count = filename:gsub(target.filename("__pattern__", "static", {plat = opt.plat}):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
if count == 0 then
- -- for the mingw/cross platform, it is compatible with the libxxx.a and xxx.lib
- local formats = {static = "lib$(name).a", shared = "lib$(name).so"}
- linkname, count = filename:gsub(target.filename("__pattern__", "static", {format = formats["static"]}):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
- if count == 0 then
- linkname, count = filename:gsub(target.filename("__pattern__", "shared", {format = formats["shared"]}):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
- end
+ linkname, count = filename:gsub(target.filename("__pattern__", "shared", {plat = opt.plat}):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
+ end
+ -- in order to be compatible with mingw/windows library with .lib
+ if count == 0 and opt.plat == "mingw" then
+ linkname, count = filename:gsub(target.filename("__pattern__", "static", {plat = "windows"}):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1")
end
return count > 0 and linkname or nil
end
diff --git a/xmake/core/sandbox/modules/debug.lua b/xmake/core/sandbox/modules/debug.lua
index a533720e7..2a3004537 100644
--- a/xmake/core/sandbox/modules/debug.lua
+++ b/xmake/core/sandbox/modules/debug.lua
@@ -24,11 +24,13 @@ local table = require("base/table")
-- define module
local sandbox_debug = sandbox_debug or table.join(debug)
-sandbox_debug.rawget = rawget
-sandbox_debug.rawset = rawset
-sandbox_debug.rawequal = rawequal
-sandbox_debug.rawlen = rawlen
-sandbox_debug.require = require
+sandbox_debug.rawget = rawget
+sandbox_debug.rawset = rawset
+sandbox_debug.rawequal = rawequal
+sandbox_debug.rawlen = rawlen
+sandbox_debug.require = require
+sandbox_debug.collectgarbage = collectgarbage
+
function sandbox_debug.global(key)
if key == nil then
return _G
@@ -36,6 +38,5 @@ function sandbox_debug.global(key)
return _G[key]
end
-
-- return module
return sandbox_debug
diff --git a/xmake/core/sandbox/modules/import/core/base/bit.lua b/xmake/core/sandbox/modules/import/core/base/bit.lua
new file mode 100644
index 000000000..3086720eb
--- /dev/null
+++ b/xmake/core/sandbox/modules/import/core/base/bit.lua
@@ -0,0 +1,24 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file bit.lua
+--
+
+-- load modules
+return require("base/bit")
+
+
diff --git a/xmake/core/sandbox/modules/import/core/base/libc.lua b/xmake/core/sandbox/modules/import/core/base/libc.lua
new file mode 100644
index 000000000..e4b6630b8
--- /dev/null
+++ b/xmake/core/sandbox/modules/import/core/base/libc.lua
@@ -0,0 +1,24 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file libc.lua
+--
+
+-- load modules
+return require("base/libc")
+
+
diff --git a/xmake/core/sandbox/modules/import/core/base/semver.lua b/xmake/core/sandbox/modules/import/core/base/semver.lua
index edaf61470..eadcfb702 100644
--- a/xmake/core/sandbox/modules/import/core/base/semver.lua
+++ b/xmake/core/sandbox/modules/import/core/base/semver.lua
@@ -80,7 +80,7 @@ end
-- local version, source = semver.select(">=1.5.0 <1.6", {"1.5.0", "1.5.1"}, {"v1.5.0", ..}, {"master", "dev"})
--
-- @version the selected version number
--- @source the version source, e.g. versions, tags, branchs
+-- @source the version source, e.g. version, tag, branch
--
function sandbox_core_base_semver.select(range, versions, tags, branches)
local verinfo, errors = semver.select(range, table.wrap(versions), table.wrap(tags), table.wrap(branches))
diff --git a/xmake/core/sandbox/modules/import/core/package/package.lua b/xmake/core/sandbox/modules/import/core/package/package.lua
index 4ba67d246..f1ec8799f 100644
--- a/xmake/core/sandbox/modules/import/core/package/package.lua
+++ b/xmake/core/sandbox/modules/import/core/package/package.lua
@@ -26,20 +26,12 @@ local project = require("project/project")
local package = require("package/package")
local raise = require("sandbox/modules/raise")
--- get cache directory
-function sandbox_core_package_package.cachedir(opt)
- return package.cachedir(opt)
-end
-
--- the install directory
-function sandbox_core_package_package.installdir()
- return package.installdir()
-end
-
--- the search directories
-function sandbox_core_package_package.searchdirs()
- return package.searchdirs()
-end
+-- inherit some builtin interfaces
+sandbox_core_package_package.cachedir = package.cachedir
+sandbox_core_package_package.installdir = package.installdir
+sandbox_core_package_package.searchdirs = package.searchdirs
+sandbox_core_package_package.targetplat = package.targetplat
+sandbox_core_package_package.targetarch = package.targetarch
-- load the package from the project file
function sandbox_core_package_package.load_from_project(packagename)
diff --git a/xmake/core/sandbox/modules/import/core/package/repository.lua b/xmake/core/sandbox/modules/import/core/package/repository.lua
index 86f27b497..5c21f5de5 100644
--- a/xmake/core/sandbox/modules/import/core/package/repository.lua
+++ b/xmake/core/sandbox/modules/import/core/package/repository.lua
@@ -29,20 +29,13 @@ local repository = require("package/repository")
local raise = require("sandbox/modules/raise")
local import = require("sandbox/modules/import")
--- get repository directory
-function sandbox_core_package_repository.directory(is_global)
- return repository.directory(is_global)
-end
-
--- get repository url from the given name
-function sandbox_core_package_repository.get(name, is_global)
- return repository.get(name, is_global)
-end
+-- inherit some builtin interfaces
+sandbox_core_package_repository.directory = repository.directory
+sandbox_core_package_repository.get = repository.get
+sandbox_core_package_repository.load = repository.load
-- add repository url to the given name
function sandbox_core_package_repository.add(name, url, branch, is_global)
-
- -- add it
local ok, errors = repository.add(name, url, branch, is_global)
if not ok then
raise(errors)
@@ -51,8 +44,6 @@ end
-- remove repository from gobal or local directory
function sandbox_core_package_repository.remove(name, is_global)
-
- -- remove it
local ok, errors = repository.remove(name, is_global)
if not ok then
raise(errors)
@@ -61,8 +52,6 @@ end
-- clear all repositories from global or local directory
function sandbox_core_package_repository.clear(is_global)
-
- -- clear all repositories
local ok, errors = repository.clear(is_global)
if not ok then
raise(errors)
@@ -92,12 +81,20 @@ function sandbox_core_package_repository.repositories(is_global)
-- in project xmake.lua:
--
-- add_repositories("other-repo https://github.com/other/other-repo.git dev")
+ -- add_repositories("other-repo dirname", {rootdir = os.scriptdir()})
--
if not is_global then
for _, repo in ipairs(table.wrap(project.get("repositories"))) do
local repoinfo = repo:split('%s')
if #repoinfo <= 3 then
- local repo = repository.load(repoinfo[1], repoinfo[2], repoinfo[3], is_global)
+ local name = repoinfo[1]
+ local url = repoinfo[2]
+ local branch = repoinfo[3]
+ local rootdir = project.extraconf("repositories", repo, "rootdir")
+ if url and rootdir and not path.is_absolute(url) and not url:find(":", 1, true) then
+ url = path.join(rootdir, url)
+ end
+ local repo = repository.load(name, url, branch, is_global)
if repo then
table.insert(repositories, repo)
end
@@ -113,15 +110,20 @@ function sandbox_core_package_repository.repositories(is_global)
-- add artifacts urls
local artifacts_urls = localcache.cache("repository"):get("artifacts_urls")
if not artifacts_urls then
- artifacts_urls = {"https://github.com/xmake-mirror/build-artifacts.git",
- "https://gitlab.com/xmake-mirror/build-artifacts.git",
- "https://gitee.com/xmake-mirror/build-artifacts.git"}
- if global.get("network") ~= "private" then
- import("net.fasturl")
- fasturl.add(artifacts_urls)
- artifacts_urls = fasturl.sort(artifacts_urls)
- localcache.cache("repository"):set("artifacts_urls", artifacts_urls)
- localcache.cache("repository"):save()
+ local binary_repo = os.getenv("XMAKE_BINARY_REPO")
+ if binary_repo then
+ artifacts_urls = {binary_repo}
+ else
+ artifacts_urls = {"https://github.com/xmake-mirror/build-artifacts.git",
+ "https://gitlab.com/xmake-mirror/build-artifacts.git",
+ "https://gitee.com/xmake-mirror/build-artifacts.git"}
+ if global.get("network") ~= "private" then
+ import("net.fasturl")
+ fasturl.add(artifacts_urls)
+ artifacts_urls = fasturl.sort(artifacts_urls)
+ localcache.cache("repository"):set("artifacts_urls", artifacts_urls)
+ localcache.cache("repository"):save()
+ end
end
end
if #artifacts_urls > 0 then
@@ -134,15 +136,20 @@ function sandbox_core_package_repository.repositories(is_global)
-- add main urls
local mainurls = localcache.cache("repository"):get("mainurls")
if not mainurls then
- mainurls = {"https://github.com/xmake-io/xmake-repo.git",
- "https://gitlab.com/tboox/xmake-repo.git",
- "https://gitee.com/tboox/xmake-repo.git"}
- if global.get("network") ~= "private" then
- import("net.fasturl")
- fasturl.add(mainurls)
- mainurls = fasturl.sort(mainurls)
- localcache.cache("repository"):set("mainurls", mainurls)
- localcache.cache("repository"):save()
+ local mainrepo = os.getenv("XMAKE_MAIN_REPO")
+ if mainrepo then
+ mainurls = {mainrepo}
+ else
+ mainurls = {"https://github.com/xmake-io/xmake-repo.git",
+ "https://gitlab.com/tboox/xmake-repo.git",
+ "https://gitee.com/tboox/xmake-repo.git"}
+ if global.get("network") ~= "private" then
+ import("net.fasturl")
+ fasturl.add(mainurls)
+ mainurls = fasturl.sort(mainurls)
+ localcache.cache("repository"):set("mainurls", mainurls)
+ localcache.cache("repository"):save()
+ end
end
end
if #mainurls > 0 then
@@ -167,3 +174,4 @@ end
-- return module
return sandbox_core_package_repository
+
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index 8e50dfb24..f515b3e74 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -36,37 +36,39 @@ local package = require("package/package")
local import = require("sandbox/modules/import")
-- export some readonly interfaces
-sandbox_core_project.get = project.get
-sandbox_core_project.extraconf = project.extraconf
-sandbox_core_project.rule = project.rule
-sandbox_core_project.rules = project.rules
-sandbox_core_project.toolchain = project.toolchain
-sandbox_core_project.toolchains = project.toolchains
-sandbox_core_project.target = project.target
-sandbox_core_project.targets = project.targets
-sandbox_core_project.ordertargets = project.ordertargets
-sandbox_core_project.option = project.option
-sandbox_core_project.options = project.options
-sandbox_core_project.rootfile = project.rootfile
-sandbox_core_project.allfiles = project.allfiles
-sandbox_core_project.rcfiles = project.rcfiles
-sandbox_core_project.directory = project.directory
-sandbox_core_project.name = project.name
-sandbox_core_project.modes = project.modes
-sandbox_core_project.default_arch = project.default_arch
-sandbox_core_project.allowed_modes = project.allowed_modes
-sandbox_core_project.allowed_plats = project.allowed_plats
-sandbox_core_project.allowed_archs = project.allowed_archs
-sandbox_core_project.mtimes = project.mtimes
-sandbox_core_project.version = project.version
-sandbox_core_project.required_package = project.required_package
-sandbox_core_project.required_packages = project.required_packages
-sandbox_core_project.requires_str = project.requires_str
-sandbox_core_project.requireconfs_str = project.requireconfs_str
-sandbox_core_project.policy = project.policy
-sandbox_core_project.tmpdir = project.tmpdir
-sandbox_core_project.tmpfile = project.tmpfile
-sandbox_core_project.is_loaded = project.is_loaded
+sandbox_core_project.get = project.get
+sandbox_core_project.extraconf = project.extraconf
+sandbox_core_project.rule = project.rule
+sandbox_core_project.rules = project.rules
+sandbox_core_project.toolchain = project.toolchain
+sandbox_core_project.toolchains = project.toolchains
+sandbox_core_project.target = project.target
+sandbox_core_project.targets = project.targets
+sandbox_core_project.ordertargets = project.ordertargets
+sandbox_core_project.option = project.option
+sandbox_core_project.options = project.options
+sandbox_core_project.rootfile = project.rootfile
+sandbox_core_project.allfiles = project.allfiles
+sandbox_core_project.rcfiles = project.rcfiles
+sandbox_core_project.directory = project.directory
+sandbox_core_project.name = project.name
+sandbox_core_project.modes = project.modes
+sandbox_core_project.default_arch = project.default_arch
+sandbox_core_project.allowed_modes = project.allowed_modes
+sandbox_core_project.allowed_plats = project.allowed_plats
+sandbox_core_project.allowed_archs = project.allowed_archs
+sandbox_core_project.mtimes = project.mtimes
+sandbox_core_project.version = project.version
+sandbox_core_project.required_package = project.required_package
+sandbox_core_project.required_packages = project.required_packages
+sandbox_core_project.requires_str = project.requires_str
+sandbox_core_project.requireconfs_str = project.requireconfs_str
+sandbox_core_project.requireslock = project.requireslock
+sandbox_core_project.requireslock_version = project.requireslock_version
+sandbox_core_project.policy = project.policy
+sandbox_core_project.tmpdir = project.tmpdir
+sandbox_core_project.tmpfile = project.tmpfile
+sandbox_core_project.is_loaded = project.is_loaded
-- check project options
function sandbox_core_project.check()
@@ -90,19 +92,15 @@ function sandbox_core_project.check()
-- init check task
local checked = {}
local checktask = function (index)
-
- -- get option
local opt = options[index]
if opt then
-
-- check deps of this option first
- for depname, dep in pairs(opt:deps()) do
- if not checked[depname] then
+ for _, dep in ipairs(opt:orderdeps()) do
+ if not checked[dep:name()] then
dep:check()
- checked[depname] = true
+ checked[dep:name()] = true
end
end
-
-- check this option
if not checked[opt:name()] then
opt:check()
@@ -112,7 +110,7 @@ function sandbox_core_project.check()
end
-- check all options
- local jobs = baseoption.get("jobs") or math.ceil(os.cpuinfo().ncpu * 3 / 2)
+ local jobs = baseoption.get("jobs") or os.default_njob()
import("private.async.runjobs", {anonymous = true})("check_options", instance:fork(checktask):script(), {total = #options, comax = jobs})
-- save all options to the cache file
@@ -161,5 +159,16 @@ function sandbox_core_project.unlock()
end
end
+-- change project file and directory (xmake.lua)
+function sandbox_core_project.chdir(projectdir, projectfile)
+ if not projectfile then
+ projectfile = path.join(projectdir, "xmake.lua")
+ end
+ xmake._PROJECT_FILE = projectfile
+ xmake._PROJECT_DIR = path.directory(projectfile)
+ xmake._WORKING_DIR = xmake._PROJECT_DIR
+ config._DIRECTORY = nil
+end
+
-- return module
return sandbox_core_project
diff --git a/xmake/core/sandbox/modules/import/core/project/target.lua b/xmake/core/sandbox/modules/import/core/project/target.lua
index 205d15d61..07424cad3 100644
--- a/xmake/core/sandbox/modules/import/core/project/target.lua
+++ b/xmake/core/sandbox/modules/import/core/project/target.lua
@@ -26,13 +26,13 @@ local target = require("project/target")
local raise = require("sandbox/modules/raise")
-- get the filename from the given name and kind
-function sandbox_core_project_target.filename(name, kind)
- return target.filename(name, kind)
+function sandbox_core_project_target.filename(name, kind, opt)
+ return target.filename(name, kind, opt)
end
-- get the link name of the target file
-function sandbox_core_project_target.linkname(filename)
- return target.linkname(filename)
+function sandbox_core_project_target.linkname(filename, opt)
+ return target.linkname(filename, opt)
end
-- return module
diff --git a/xmake/core/sandbox/modules/import/core/sandbox/module.lua b/xmake/core/sandbox/modules/import/core/sandbox/module.lua
index f5b45f6f8..ab859ab95 100644
--- a/xmake/core/sandbox/modules/import/core/sandbox/module.lua
+++ b/xmake/core/sandbox/modules/import/core/sandbox/module.lua
@@ -28,6 +28,7 @@ local utils = require("base/utils")
local table = require("base/table")
local string = require("base/string")
local global = require("base/global")
+local memcache = require("cache/memcache")
local sandbox = require("sandbox/sandbox")
local raise = require("sandbox/modules/raise")
@@ -287,31 +288,27 @@ end
-- get module directories
function core_sandbox_module.directories()
- local directories = core_sandbox_module._DIRS
- if not directories then
- directories = { path.join(global.directory(), "modules"),
- path.join(os.programdir(), "modules"),
- path.join(os.programdir(), "core/sandbox/modules/import")}
+ local moduledirs = memcache.get("core_sandbox_module", "moduledirs")
+ if not moduledirs then
+ moduledirs = { path.join(global.directory(), "modules"),
+ path.join(os.programdir(), "modules"),
+ path.join(os.programdir(), "core/sandbox/modules/import")}
local modulesdir = os.getenv("XMAKE_MODULES_DIR")
if modulesdir and os.isdir(modulesdir) then
- table.insert(directories, 1, modulesdir)
+ table.insert(moduledirs, 1, modulesdir)
end
- core_sandbox_module._DIRS = directories
+ memcache.set("core_sandbox_module", "moduledirs", moduledirs)
end
- return directories
+ return moduledirs
end
-- add module directories
function core_sandbox_module.add_directories(...)
-
- -- add directories
local moduledirs = core_sandbox_module.directories()
for _, dir in ipairs({...}) do
table.insert(moduledirs, 1, dir)
end
-
- -- remove unique directories
- core_sandbox_module._DIRS = table.unique(moduledirs)
+ memcache.set("core_sandbox_module", "moduledirs", table.unique(moduledirs))
end
-- find module
diff --git a/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua b/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua
index c8a44d266..c189f398e 100644
--- a/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua
+++ b/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua
@@ -93,6 +93,7 @@ function sandbox_core_sandbox.interactive()
public_scope["$interactive_dump"] = sandbox_core_sandbox._interactive_dump
public_scope["$interactive_prompt"] = colors.translate("${color.interactive.prompt}${text.interactive.prompt} ")
public_scope["$interactive_prompt2"] = colors.translate("${color.interactive.prompt2}${text.interactive.prompt2} ")
+ public_scope["$interactive_setfenv"] = setfenv
-- disable scheduler
scheduler:enable(false)
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_library.lua b/xmake/core/sandbox/modules/import/lib/detect/find_library.lua
index bfb2315a5..4fb2618d3 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_library.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_library.lua
@@ -38,7 +38,7 @@ local find_file = import("lib.detect.find_file")
-- @param paths the search paths
-- @param opt the options, e.g. {kind = "static/shared", suffixes = {"/aa", "/bb"}}
--
--- @return {kind = "static", link = "crypto", linkdir = "/usr/local/lib", filename = "libcrypto.a"}
+-- @return {kind = "static", link = "crypto", linkdir = "/usr/local/lib", filename = "libcrypto.a", plat = ..}
--
-- @code
--
@@ -54,24 +54,26 @@ function sandbox_lib_detect_find_library.main(names, paths, opt)
return
end
- -- init options
+ -- find library file from the given paths
opt = opt or {}
-
- -- init kinds
local kinds = opt.kind or {"static", "shared"}
-
- -- find library file from the given paths
for _, name in ipairs(table.wrap(names)) do
for _, kind in ipairs(table.wrap(kinds)) do
- local filepath = find_file(target.filename(name, kind), paths, opt)
- if not filepath then
- -- for the mingw/cross platform, it is compatible with the libxxx.a and xxx.lib
- local formats = {static = "lib$(name).a", shared = "lib$(name).so"}
- filepath = find_file(target.filename(name, kind, {format = formats[kind]}), paths, opt)
+ local filepath = find_file(target.filename(name, kind, {plat = opt.plat}), paths, opt)
+ if opt.plat == "mingw" then
+ if not filepath and kind == "shared" then
+ -- for implib/mingw, e.g. libxxx.dll.a
+ filepath = find_file(target.filename(name, kind, {plat = opt.plat}) .. ".a", paths, opt)
+ end
+ if not filepath then
+ -- in order to be compatible with mingw/windows library with .lib
+ filepath = find_file(target.filename(name, kind, {plat = "windows"}), paths, opt)
+ end
end
if filepath then
local filename = path.filename(filepath)
- return {kind = kind, filename = filename, linkdir = path.directory(filepath), link = target.linkname(filename)}
+ local linkname = target.linkname(filename, {plat = opt.plat})
+ return {kind = kind, filename = filename, linkdir = path.directory(filepath), link = linkname}
end
end
end
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
index 4e5eadc14..59a01f746 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
@@ -139,7 +139,9 @@ end
function sandbox_lib_detect_find_program._find_from_packages(name, opt)
-- get the manifest file of package, e.g. ~/.xmake/packages/g/git/1.1.12/ed41d5327fad3fc06fe376b4a94f62ef/manifest.txt
- local manifest_file = path.join(package.installdir(), name:sub(1, 1), name, opt.require_version, opt.buildhash, "manifest.txt")
+ opt = opt or {}
+ local installdir = opt.installdir or path.join(package.installdir(), name:sub(1, 1), name, opt.require_version, opt.buildhash)
+ local manifest_file = path.join(installdir, "manifest.txt")
if not os.isfile(manifest_file) then
return
end
diff --git a/xmake/core/sandbox/modules/interpreter/os.lua b/xmake/core/sandbox/modules/interpreter/os.lua
index 10c4b710c..dff4a14d7 100644
--- a/xmake/core/sandbox/modules/interpreter/os.lua
+++ b/xmake/core/sandbox/modules/interpreter/os.lua
@@ -27,27 +27,28 @@ local interpreter = require("base/interpreter")
local sandbox_os = sandbox_os or {}
-- export some readonly interfaces
-sandbox_os.term = os.term
-sandbox_os.host = os.host
-sandbox_os.arch = os.arch
-sandbox_os.subhost = os.subhost
-sandbox_os.subarch = os.subarch
-sandbox_os.date = os.date
-sandbox_os.time = os.time
-sandbox_os.mtime = os.mtime
-sandbox_os.mclock = os.mclock
-sandbox_os.getenv = os.getenv
-sandbox_os.isdir = os.isdir
-sandbox_os.isfile = os.isfile
-sandbox_os.exists = os.exists
-sandbox_os.curdir = os.curdir
-sandbox_os.tmpdir = os.tmpdir
-sandbox_os.cpuinfo = os.cpuinfo
-sandbox_os.filesize = os.filesize
-sandbox_os.programdir = os.programdir
-sandbox_os.programfile = os.programfile
-sandbox_os.projectdir = os.projectdir
-sandbox_os.projectfile = os.projectfile
+sandbox_os.term = os.term
+sandbox_os.host = os.host
+sandbox_os.arch = os.arch
+sandbox_os.subhost = os.subhost
+sandbox_os.subarch = os.subarch
+sandbox_os.date = os.date
+sandbox_os.time = os.time
+sandbox_os.mtime = os.mtime
+sandbox_os.mclock = os.mclock
+sandbox_os.getenv = os.getenv
+sandbox_os.isdir = os.isdir
+sandbox_os.isfile = os.isfile
+sandbox_os.exists = os.exists
+sandbox_os.curdir = os.curdir
+sandbox_os.tmpdir = os.tmpdir
+sandbox_os.cpuinfo = os.cpuinfo
+sandbox_os.default_njob = os.default_njob
+sandbox_os.filesize = os.filesize
+sandbox_os.programdir = os.programdir
+sandbox_os.programfile = os.programfile
+sandbox_os.projectdir = os.projectdir
+sandbox_os.projectfile = os.projectfile
-- match files
function sandbox_os.files(pattern, ...)
diff --git a/xmake/core/sandbox/modules/interpreter/print.lua b/xmake/core/sandbox/modules/interpreter/print.lua
index 0f906f5a4..dd42c8fe9 100644
--- a/xmake/core/sandbox/modules/interpreter/print.lua
+++ b/xmake/core/sandbox/modules/interpreter/print.lua
@@ -19,6 +19,7 @@
--
-- load modules
+local table = require("base/table")
local try = require("sandbox/modules/try")
local catch = require("sandbox/modules/catch")
@@ -33,13 +34,13 @@ function _print(format, ...)
{
function ()
-- attempt to print format string first
- io.write(string.format(format, unpack(args)) .. "\n")
+ io.write(string.format(format, table.unpack(args)) .. "\n")
end,
catch
{
function ()
-- print multi-variables with raw lua action
- print(format, unpack(args))
+ print(format, table.unpack(args))
end
}
}
diff --git a/xmake/core/sandbox/modules/interpreter/unpack.lua b/xmake/core/sandbox/modules/interpreter/unpack.lua
index 766e49f98..5d3b9c811 100644
--- a/xmake/core/sandbox/modules/interpreter/unpack.lua
+++ b/xmake/core/sandbox/modules/interpreter/unpack.lua
@@ -15,9 +15,9 @@
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki
--- @file unpack.lua
+-- @file table.unpack.lua
--
-- load module
-return unpack
+return require("base/table").unpack
diff --git a/xmake/core/sandbox/modules/interpreter/xmake.lua b/xmake/core/sandbox/modules/interpreter/xmake.lua
index 414258198..fcc6437e1 100644
--- a/xmake/core/sandbox/modules/interpreter/xmake.lua
+++ b/xmake/core/sandbox/modules/interpreter/xmake.lua
@@ -28,6 +28,7 @@ local sandbox_xmake = sandbox_xmake or {}
sandbox_xmake.version = xmake.version
sandbox_xmake.programdir = xmake.programdir
sandbox_xmake.programfile = xmake.programfile
+sandbox_xmake.luajit = xmake.luajit
-- return module
return sandbox_xmake
diff --git a/xmake/core/sandbox/modules/irpairs.lua b/xmake/core/sandbox/modules/irpairs.lua
index 7cb175173..d59574481 100644
--- a/xmake/core/sandbox/modules/irpairs.lua
+++ b/xmake/core/sandbox/modules/irpairs.lua
@@ -60,7 +60,7 @@ function sandbox_irpairs(t, filter, ...)
-- return iterator and initialized state
t = table.wrap(t)
- return iter, t, table.maxn(t) + 1
+ return iter, t, table.getn(t) + 1
end
-- load module
diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua
index beb60ddab..9f6fcd8d8 100644
--- a/xmake/core/sandbox/modules/os.lua
+++ b/xmake/core/sandbox/modules/os.lua
@@ -65,6 +65,7 @@ sandbox_os.joinenvs = os.joinenvs
sandbox_os.pbpaste = os.pbpaste
sandbox_os.pbcopy = os.pbcopy
sandbox_os.cpuinfo = os.cpuinfo
+sandbox_os.default_njob = os.default_njob
sandbox_os.emptydir = os.emptydir
sandbox_os.filesize = os.filesize
sandbox_os.features = os.features
diff --git a/xmake/core/sandbox/modules/unpack.lua b/xmake/core/sandbox/modules/unpack.lua
index 766e49f98..5d3b9c811 100644
--- a/xmake/core/sandbox/modules/unpack.lua
+++ b/xmake/core/sandbox/modules/unpack.lua
@@ -15,9 +15,9 @@
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki
--- @file unpack.lua
+-- @file table.unpack.lua
--
-- load module
-return unpack
+return require("base/table").unpack
diff --git a/xmake/core/sandbox/modules/utils.lua b/xmake/core/sandbox/modules/utils.lua
index 528f59b9e..b2f9a682a 100644
--- a/xmake/core/sandbox/modules/utils.lua
+++ b/xmake/core/sandbox/modules/utils.lua
@@ -55,10 +55,10 @@ function sandbox_utils._print(...)
end
-- print multi-variables with raw lua action
- utils._print(unpack(args))
+ utils._print(table.unpack(args))
-- write to the log file
- log:printv(unpack(args))
+ log:printv(table.unpack(args))
end
-- print format string with newline
@@ -75,7 +75,7 @@ function sandbox_utils.print(format, ...)
{
function ()
-- attempt to format message
- local message = vformat(format, unpack(args))
+ local message = vformat(format, table.unpack(args))
-- trace
utils._print(message)
@@ -87,7 +87,7 @@ function sandbox_utils.print(format, ...)
{
function (errors)
-- print multi-variables with raw lua action
- sandbox_utils._print(format, unpack(args))
+ sandbox_utils._print(format, table.unpack(args))
end
}
}
diff --git a/xmake/core/sandbox/modules/winos.lua b/xmake/core/sandbox/modules/winos.lua
index 0a0192470..6bc5ce0c4 100644
--- a/xmake/core/sandbox/modules/winos.lua
+++ b/xmake/core/sandbox/modules/winos.lua
@@ -70,6 +70,15 @@ function sandbox_winos.registry_values(keypath)
return values
end
+-- get short path
+function sandbox_winos.short_path(long_path)
+ local short_path, errors = winos.short_path(long_path)
+ if not short_path then
+ raise(errors)
+ end
+ return short_path
+end
+
-- return module
return sandbox_winos
diff --git a/xmake/core/sandbox/modules/xmake.lua b/xmake/core/sandbox/modules/xmake.lua
index 414258198..70e5f5e36 100644
--- a/xmake/core/sandbox/modules/xmake.lua
+++ b/xmake/core/sandbox/modules/xmake.lua
@@ -26,8 +26,10 @@ local sandbox_xmake = sandbox_xmake or {}
-- inherit some builtin interfaces
sandbox_xmake.version = xmake.version
+sandbox_xmake.branch = xmake.branch
sandbox_xmake.programdir = xmake.programdir
sandbox_xmake.programfile = xmake.programfile
+sandbox_xmake.luajit = xmake.luajit
-- return module
return sandbox_xmake
diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua
index 33733eaab..343eec0ae 100644
--- a/xmake/core/tool/builder.lua
+++ b/xmake/core/tool/builder.lua
@@ -420,8 +420,8 @@ function builder:get(name)
end
-- has flags?
-function builder:has_flags(flags, flagkind)
- return self:_tool():has_flags(flags, flagkind)
+function builder:has_flags(flags, flagkind, opt)
+ return self:_tool():has_flags(flags, flagkind, opt)
end
-- map flags from name and values, e.g. linkdirs, links, defines
@@ -442,13 +442,5 @@ function builder:map_flags(name, values, opt)
end
end
--- get the format of the given target kind
-function builder:format(targetkind)
- local formats = self:get("formats")
- if formats then
- return formats[targetkind]
- end
-end
-
-- return module
return builder
diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua
index 0e64de8c3..745453e0f 100644
--- a/xmake/core/tool/compiler.lua
+++ b/xmake/core/tool/compiler.lua
@@ -74,6 +74,22 @@ function compiler:_add_flags_from_compiler(flags, targetkind)
end
end
+-- add flags from the sourcefile config
+function compiler:_add_flags_from_fileconfig(flags, target, sourcefile, fileconfig)
+
+ -- add flags from the current compiler
+ local add_sourceflags = self:_tool().add_sourceflags
+ if add_sourceflags then
+ local flag = add_sourceflags(self:_tool(), sourcefile, fileconfig, target, self:_targetkind())
+ if flag and flag ~= "" then
+ table.join2(flags, flag)
+ end
+ end
+
+ -- add flags from the common argument option
+ self:_add_flags_from_argument(flags, target, fileconfig)
+end
+
-- load compiler tool
function compiler._load_tool(sourcekind, target)
@@ -95,6 +111,9 @@ end
-- load the compiler from the given source kind
function compiler.load(sourcekind, target)
+ if not sourcekind then
+ return nil, "unknown source kind!"
+ end
-- load compiler tool first (with cache)
local compiler_tool, program_or_errors = compiler._load_tool(sourcekind, target)
@@ -262,29 +281,13 @@ function compiler:compcmd(sourcefiles, objectfile, opt)
return os.args(table.join(self:compargv(sourcefiles, objectfile, opt)))
end
--- add flags from the sourcefile config
-function builder:_add_flags_from_fileconfig(flags, target, sourcefile, fileconfig)
-
- -- add flags from the current compiler
- local add_sourceflags = self:_tool().add_sourceflags
- if add_sourceflags then
- local flag = add_sourceflags(self:_tool(), sourcefile, fileconfig, target, self:_targetkind())
- if flag and flag ~= "" then
- table.join2(flags, flag)
- end
- end
-
- -- add flags from the common argument option
- self:_add_flags_from_argument(flags, target, fileconfig)
-end
-
-- get the compling flags
--
-- @param opt the argument options (contain all the compiler attributes of target),
-- e.g.
-- {target = ..., targetkind = "static", configs = {defines = "", cxflags = "", includedirs = ""}}
--
--- @return flags string, flags list
+-- @return flags list
--
function compiler:compflags(opt)
diff --git a/xmake/core/tool/tool.lua b/xmake/core/tool/tool.lua
index c118179d6..af62c7f8e 100644
--- a/xmake/core/tool/tool.lua
+++ b/xmake/core/tool/tool.lua
@@ -140,8 +140,8 @@ function _instance:has_flags(flags, flagkind, opt)
-- get system flags
opt.sysflags = opt.sysflags or self:get(self:kind() .. 'flags')
- if not opt.sysflags and flagkind then
- opt.sysflags = self:get(flagkind)
+ if not opt.sysflags and opt.flagkind then
+ opt.sysflags = self:get(opt.flagkind)
end
-- import has_flags()
diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua
index 868d05746..f4a511f0f 100644
--- a/xmake/core/tool/toolchain.lua
+++ b/xmake/core/tool/toolchain.lua
@@ -131,7 +131,7 @@ function _instance:get(name)
return value
end
- -- lazy loading platform
+ -- lazy loading toolchain
self:_load()
-- get other platform info
@@ -185,6 +185,7 @@ end
-- get the program and name of the given tool kind
function _instance:tool(toolkind)
-- ensure to do load for initializing toolset first
+ -- @note we cannot call self:check() here, because it can only be called on config
self:_load()
local toolpaths = self:get("toolset." .. toolkind)
if toolpaths then
@@ -210,7 +211,7 @@ end
-- get the bin directory
function _instance:bindir()
local bindir = self:config("bindir") or config.get("bin") or self:info():get("bindir")
- if not bindir and self:cross() and self:sdkdir() and os.isdir(path.join(self:sdkdir(), "bin")) then
+ if not bindir and self:is_cross() and self:sdkdir() and os.isdir(path.join(self:sdkdir(), "bin")) then
bindir = path.join(self:sdkdir(), "bin")
end
return bindir
@@ -338,7 +339,6 @@ function _instance:_description(toolkind)
ld = "the linker",
sh = "the shared library linker",
ar = "the static library archiver",
- ex = "the static library extractor",
mrc = "the windows resource compiler",
strip = "the symbols stripper",
dsymutil = "the symbols generator",
@@ -369,6 +369,10 @@ function _instance:_description(toolkind)
cu = "the cuda compiler",
culd = "the cuda linker",
cuccbin = "the cuda host c++ compiler",
+ nc = "the nim compiler",
+ ncld = "the nim linker",
+ ncsh = "the nim shared library linker",
+ ncar = "the nim static library archiver"
}
self._DESCRIPTIONS = descriptions
end
diff --git a/xmake/core/ui/label.lua b/xmake/core/ui/label.lua
index 95a78112f..02aa7245d 100644
--- a/xmake/core/ui/label.lua
+++ b/xmake/core/ui/label.lua
@@ -24,7 +24,7 @@ local view = require("ui/view")
local event = require("ui/event")
local action = require("ui/action")
local curses = require("ui/curses")
-local bit = require("bit")
+local bit = require("base/bit")
-- define module
local label = label or view()
diff --git a/xmake/core/ui/program.lua b/xmake/core/ui/program.lua
index 0ebd6377a..49eff8679 100644
--- a/xmake/core/ui/program.lua
+++ b/xmake/core/ui/program.lua
@@ -345,6 +345,15 @@ function program:_key_map()
[curses.KEY_SHOME ] = "ShiftHome",
[curses.KEY_SLEFT ] = "ShiftLeft",
[curses.KEY_SRIGHT ] = "ShiftRight",
+
+ -- register virtual keys
+ --
+ -- @see https://github.com/xmake-io/xmake/issues/1610
+ -- https://github.com/wmcbrine/PDCurses/blob/HEAD/curses.h#L766-L774
+ [curses.KEY_C2 or -1 ] = "Down",
+ [curses.KEY_A2 or -1 ] = "Up",
+ [curses.KEY_B1 or -1 ] = "Left",
+ [curses.KEY_B3 or -1 ] = "Right"
}
end
return self._KEYMAP
diff --git a/xmake/core/ui/textedit.lua b/xmake/core/ui/textedit.lua
index 44a10d074..744858fb6 100644
--- a/xmake/core/ui/textedit.lua
+++ b/xmake/core/ui/textedit.lua
@@ -27,7 +27,7 @@ local border = require("ui/border")
local curses = require("ui/curses")
local textarea = require("ui/textarea")
local action = require("ui/action")
-local bit = require("bit")
+local bit = require("base/bit")
-- define module
local textedit = textedit or textarea()
diff --git a/xmake/includes/check_cflags.lua b/xmake/includes/check_cflags.lua
index 85ee65f8e..63354dfac 100644
--- a/xmake/includes/check_cflags.lua
+++ b/xmake/includes/check_cflags.lua
@@ -23,11 +23,12 @@
-- e.g.
--
-- check_cflags("HAS_SSE2", "-msse2")
--- check_cflags("HAS_SSE2", {"-msse2", "/arch:SSE2"})
+-- check_cflags("HAS_SSE2", {"-msse", "-msse2"})
--
function check_cflags(definition, flags, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_defines(definition)
on_check(function (option)
@@ -37,6 +38,7 @@ function check_cflags(definition, flags, opt)
end
end)
option_end()
+ restore_scope()
add_options(optname)
end
@@ -45,15 +47,20 @@ end
-- e.g.
--
-- configvar_check_cflags("HAS_SSE2", "-msse2")
--- configvar_check_cflags("HAS_SSE2", {"-msse2", "/arch:SSE2"})
--- configvar_check_cflags("SSE=2", "-msse2")
+-- configvar_check_cflags("HAS_SSE2", {"-msse", "-msse2"})
+-- configvar_check_cflags("HAS_SSE2", "-msse2", {default = 0})
+-- configvar_check_cflags("SSE_STR=2", "-msse2")
+-- configvar_check_cflags("SSE=2", "-msse2", {quote = false})
--
function configvar_check_cflags(definition, flags, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
on_check(function (option)
import("core.tool.compiler")
if compiler.has_flags("c", flags, opt) then
@@ -61,5 +68,10 @@ function configvar_check_cflags(definition, flags, opt)
end
end)
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cfuncs.lua b/xmake/includes/check_cfuncs.lua
index 337a16fac..51352e424 100644
--- a/xmake/includes/check_cfuncs.lua
+++ b/xmake/includes/check_cfuncs.lua
@@ -34,6 +34,7 @@
function check_cfuncs(definition, funcs, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_cfuncs(funcs)
add_defines(definition)
@@ -49,7 +50,7 @@ function check_cfuncs(definition, funcs, opt)
if opt.cflags then
add_cflags(opt.cflags)
end
- if opt.cflags then
+ if opt.cxflags then
add_cxflags(opt.cxflags)
end
if opt.defines then
@@ -59,6 +60,7 @@ function check_cfuncs(definition, funcs, opt)
set_warnings(opt.warnings)
end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -68,14 +70,19 @@ end
--
-- configvar_check_cfuncs("HAS_SETJMP", "setjmp", {includes = {"signal.h", "setjmp.h"}, links = {}})
-- configvar_check_cfuncs("HAS_SETJMP", {"setjmp", "sigsetjmp{sigsetjmp((void*)0, 0);}"})
+-- configvar_check_cfuncs("HAS_SETJMP", "setjmp", {includes = {"setjmp.h"}, default = 0})
+-- configvar_check_cfuncs("CUSTOM_SETJMP=setjmp", "setjmp", {includes = {"setjmp.h"}, default = "", quote = false})
--
function configvar_check_cfuncs(definition, funcs, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_cfuncs(funcs)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.links then
add_links(opt.links)
end
@@ -98,5 +105,10 @@ function configvar_check_cfuncs(definition, funcs, opt)
set_warnings(opt.warnings)
end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cincludes.lua b/xmake/includes/check_cincludes.lua
index d5e4cf4a3..c954b5260 100644
--- a/xmake/includes/check_cincludes.lua
+++ b/xmake/includes/check_cincludes.lua
@@ -28,10 +28,15 @@
function check_cincludes(definition, includes, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_cincludes(includes)
+ if opt.includedirs then
+ add_includedirs(opt.includedirs)
+ end
add_defines(definition)
option_end()
+ restore_scope()
add_options(optname)
end
@@ -40,15 +45,27 @@ end
-- e.g.
--
-- configvar_check_cincludes("HAS_STRING_H", "string.h")
+-- configvar_check_cincludes("HAS_STRING_H", "string.h", {default = 0})
-- configvar_check_cincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"})
--
function configvar_check_cincludes(definition, includes, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_cincludes(includes)
- set_configvar(defname, defval or 1)
+ if opt.includedirs then
+ add_includedirs(opt.includedirs)
+ end
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_csnippets.lua b/xmake/includes/check_csnippets.lua
index 6cd4ccdc9..19e87ab9e 100644
--- a/xmake/includes/check_csnippets.lua
+++ b/xmake/includes/check_csnippets.lua
@@ -23,13 +23,18 @@
-- e.g.
--
-- check_csnippets("HAS_STATIC_ASSERT", "_Static_assert(1, \"\");", {includes = "stdio.h"})
+-- check_csnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true})
+-- check_csnippets("PTR_SIZE", 'printf("%d", sizeof(void*)); return 0;', {output = true, number = true})
--
function check_csnippets(definition, snippets, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
- add_csnippets(definition, snippets)
- add_defines(definition)
+ add_csnippets(definition, snippets, {tryrun = opt.tryrun, output = opt.output})
+ if not opt.output then
+ add_defines(definition)
+ end
if opt.links then
add_links(opt.links)
end
@@ -51,7 +56,21 @@ function check_csnippets(definition, snippets, opt)
if opt.warnings then
set_warnings(opt.warnings)
end
+ if opt.output then
+ after_check(function (option)
+ if option:value() then
+ if opt.number then
+ option:add("defines", definition .. "=" .. tonumber(option:value()))
+ elseif opt.quote == false then
+ option:add("defines", definition .. "=" .. option:value())
+ else
+ option:add("defines", definition .. "=\"" .. option:value() .. "\"")
+ end
+ end
+ end)
+ end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -60,14 +79,21 @@ end
-- e.g.
--
-- configvar_check_csnippets("HAS_STATIC_ASSERT", "_Static_assert(1, \"\");", {includes = "stdio.h"})
+-- configvar_check_csnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true})
+-- configvar_check_csnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true, default = 0})
+-- configvar_check_csnippets("LONG_SIZE=8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true, quote = false})
+-- configvar_check_csnippets("PTR_SIZE", 'printf("%d", sizeof(void*)); return 0;', {output = true, number = true})
--
function configvar_check_csnippets(definition, snippets, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
- add_csnippets(definition, snippets)
- set_configvar(defname, defval or 1)
+ add_csnippets(definition, snippets, {tryrun = opt.tryrun, output = opt.output})
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.links then
add_links(opt.links)
end
@@ -89,6 +115,18 @@ function configvar_check_csnippets(definition, snippets, opt)
if opt.warnings then
set_warnings(opt.warnings)
end
+ if opt.output then
+ after_check(function (option)
+ if option:value() then
+ option:set("configvar", defname, opt.number and tonumber(option:value()) or option:value(), {quote = opt.quote})
+ end
+ end)
+ end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_ctypes.lua b/xmake/includes/check_ctypes.lua
index d6bf77f82..d14c64aa7 100644
--- a/xmake/includes/check_ctypes.lua
+++ b/xmake/includes/check_ctypes.lua
@@ -28,6 +28,7 @@
function check_ctypes(definition, types, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_ctypes(types)
add_defines(definition)
@@ -47,6 +48,7 @@ function check_ctypes(definition, types, opt)
add_cincludes(opt.includes)
end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -55,15 +57,20 @@ end
-- e.g.
--
-- configvar_check_ctypes("HAS_WCHAR", "wchar_t")
+-- configvar_check_ctypes("HAS_WCHAR", "wchar_t", {default = 0})
+-- configvar_check_ctypes("CUSTOM_WCHAR=wchar_t", "wchar_t", {default = "", quote = false})
-- configvar_check_ctypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"})
--
function configvar_check_ctypes(definition, types, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_ctypes(types)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.languages then
set_languages(opt.languages)
end
@@ -80,5 +87,10 @@ function configvar_check_ctypes(definition, types, opt)
add_cincludes(opt.includes)
end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cxxflags.lua b/xmake/includes/check_cxxflags.lua
index c2881ecdc..c93745134 100644
--- a/xmake/includes/check_cxxflags.lua
+++ b/xmake/includes/check_cxxflags.lua
@@ -23,11 +23,12 @@
-- e.g.
--
-- check_cxxflags("HAS_SSE2", "-msse2")
--- check_cxxflags("HAS_SSE2", {"-msse2", "/arch:SSE2"})
+-- check_cxxflags("HAS_SSE2", {"-msse", "-msse2"})
--
function check_cxxflags(definition, flags, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_defines(definition)
on_check(function (option)
@@ -37,6 +38,7 @@ function check_cxxflags(definition, flags, opt)
end
end)
option_end()
+ restore_scope()
add_options(optname)
end
@@ -45,15 +47,20 @@ end
-- e.g.
--
-- configvar_check_cxxflags("HAS_SSE2", "-msse2")
--- configvar_check_cxxflags("HAS_SSE2", {"-msse2", "/arch:SSE2"})
--- configvar_check_cxxflags("SSE=2", "-msse2")
+-- configvar_check_cxxflags("HAS_SSE2", {"-msse", "-msse2"})
+-- configvar_check_cxxflags("HAS_SSE2", "-msse2", {default = 0})
+-- configvar_check_cxxflags("SSE_STR=2", "-msse2")
+-- configvar_check_cxxflags("SSE=2", "-msse2", {quote = false})
--
function configvar_check_cxxflags(definition, flags, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
on_check(function (option)
import("core.tool.compiler")
if compiler.has_flags("cxx", flags, opt) then
@@ -61,5 +68,10 @@ function configvar_check_cxxflags(definition, flags, opt)
end
end)
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cxxfuncs.lua b/xmake/includes/check_cxxfuncs.lua
index bef5d8252..241effd19 100644
--- a/xmake/includes/check_cxxfuncs.lua
+++ b/xmake/includes/check_cxxfuncs.lua
@@ -34,6 +34,7 @@
function check_cxxfuncs(definition, funcs, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_cxxfuncs(funcs)
add_defines(definition)
@@ -59,6 +60,7 @@ function check_cxxfuncs(definition, funcs, opt)
set_warnings(opt.warnings)
end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -68,14 +70,19 @@ end
--
-- configvar_check_cxxfuncs("HAS_SETJMP", "setjmp", {includes = {"signal.h", "setjmp.h"}, links = {}})
-- configvar_check_cxxfuncs("HAS_SETJMP", {"setjmp", "sigsetjmp{sigsetjmp((void*)0, 0);}"})
+-- configvar_check_cxxfuncs("HAS_SETJMP", "setjmp", {includes = {"setjmp.h"}, default = 0})
+-- configvar_check_cxxfuncs("CUSTOM_SETJMP=setjmp", "setjmp", {includes = {"setjmp.h"}, default = "", quote = false})
--
function configvar_check_cxxfuncs(definition, funcs, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_cxxfuncs(funcs)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.links then
add_links(opt.links)
end
@@ -98,5 +105,10 @@ function configvar_check_cxxfuncs(definition, funcs, opt)
set_warnings(opt.warnings)
end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cxxincludes.lua b/xmake/includes/check_cxxincludes.lua
index 4ef52b155..15f4fa1df 100644
--- a/xmake/includes/check_cxxincludes.lua
+++ b/xmake/includes/check_cxxincludes.lua
@@ -28,10 +28,12 @@
function check_cxxincludes(definition, includes, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_cxxincludes(includes)
add_defines(definition)
option_end()
+ restore_scope()
add_options(optname)
end
@@ -40,15 +42,24 @@ end
-- e.g.
--
-- configvar_check_cxxincludes("HAS_STRING_H", "string.h")
+-- configvar_check_cxxincludes("HAS_STRING_H", "string.h", {default = 0})
-- configvar_check_cxxincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"})
--
function configvar_check_cxxincludes(definition, includes, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_cxxincludes(includes)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cxxsnippets.lua b/xmake/includes/check_cxxsnippets.lua
index 2e906100b..9405b5707 100644
--- a/xmake/includes/check_cxxsnippets.lua
+++ b/xmake/includes/check_cxxsnippets.lua
@@ -23,13 +23,18 @@
-- e.g.
--
-- check_cxxsnippets("HAS_STATIC_ASSERT", "static_assert(1, \"\");")
+-- check_csnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true})
+-- check_csnippets("PTR_SIZE", 'printf("%d", sizeof(void*)); return 0;', {output = true, number = true})
--
function check_cxxsnippets(definition, snippets, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
- add_cxxsnippets(definition, snippets)
- add_defines(definition)
+ add_cxxsnippets(definition, snippets, {tryrun = opt.tryrun, output = opt.output})
+ if not opt.output then
+ add_defines(definition)
+ end
if opt.links then
add_links(opt.links)
end
@@ -51,7 +56,21 @@ function check_cxxsnippets(definition, snippets, opt)
if opt.warnings then
set_warnings(opt.warnings)
end
+ if opt.output then
+ after_check(function (option)
+ if option:value() then
+ if opt.number then
+ option:add("defines", definition .. "=" .. tonumber(option:value()))
+ elseif opt.quote == false then
+ option:add("defines", definition .. "=" .. option:value())
+ else
+ option:add("defines", definition .. "=\"" .. option:value() .. "\"")
+ end
+ end
+ end)
+ end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -60,14 +79,21 @@ end
-- e.g.
--
-- configvar_check_cxxsnippets("HAS_STATIC_ASSERT", "static_assert(1, \"\");")
+-- configvar_check_cxxsnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true})
+-- configvar_check_cxxsnippets("HAS_LONG_8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true, default = 0})
+-- configvar_check_cxxsnippets("LONG_SIZE=8", "return (sizeof(long) == 8)? 0 : -1;", {tryrun = true, quote = false})
+-- configvar_check_cxxsnippets("PTR_SIZE", 'printf("%d", sizeof(void*)); return 0;', {output = true, number = true})
--
function configvar_check_cxxsnippets(definition, snippets, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
- add_cxxsnippets(definition, snippets)
- set_configvar(defname, defval or 1)
+ add_cxxsnippets(definition, snippets, {tryrun = opt.tryrun, output = opt.output})
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.links then
add_links(opt.links)
end
@@ -89,6 +115,18 @@ function configvar_check_cxxsnippets(definition, snippets, opt)
if opt.warnings then
set_warnings(opt.warnings)
end
+ if opt.output then
+ after_check(function (option)
+ if option:value() then
+ option:set("configvar", defname, opt.number and tonumber(option:value()) or option:value(), {quote = opt.quote})
+ end
+ end)
+ end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_cxxtypes.lua b/xmake/includes/check_cxxtypes.lua
index 859e26c4d..928ecbad5 100644
--- a/xmake/includes/check_cxxtypes.lua
+++ b/xmake/includes/check_cxxtypes.lua
@@ -28,6 +28,7 @@
function check_cxxtypes(definition, types, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_cxxtypes(types)
add_defines(definition)
@@ -47,6 +48,7 @@ function check_cxxtypes(definition, types, opt)
add_cxxincludes(opt.includes)
end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -55,15 +57,20 @@ end
-- e.g.
--
-- configvar_check_cxxtypes("HAS_WCHAR", "wchar_t")
+-- configvar_check_cxxtypes("HAS_WCHAR", "wchar_t", {default = 0})
+-- configvar_check_cxxtypes("CUSTOM_WCHAR=wchar_t", "wchar_t", {default = "", quote = false})
-- configvar_check_cxxtypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"})
--
function configvar_check_cxxtypes(definition, types, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_cxxtypes(types)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.languages then
set_languages(opt.languages)
end
@@ -80,5 +87,10 @@ function configvar_check_cxxtypes(definition, types, opt)
add_cxxincludes(opt.includes)
end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_features.lua b/xmake/includes/check_features.lua
index 1340d32f5..481d9b6fe 100644
--- a/xmake/includes/check_features.lua
+++ b/xmake/includes/check_features.lua
@@ -28,6 +28,7 @@
function check_features(definition, features, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_features(features)
add_defines(definition)
@@ -44,6 +45,7 @@ function check_features(definition, features, opt)
add_cxxflags(opt.cxxflags)
end
option_end()
+ restore_scope()
add_options(optname)
end
@@ -52,15 +54,19 @@ end
-- e.g.
--
-- configvar_check_features("HAS_CONSTEXPR", "cxx_constexpr")
+-- configvar_check_features("HAS_CONSTEXPR", "cxx_constexpr", {default = 0})
-- configvar_check_features("HAS_CONSEXPR_AND_STATIC_ASSERT", {"cxx_constexpr", "c_static_assert"}, {languages = "c++11"})
--
function configvar_check_features(definition, features, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_features(features)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
if opt.languages then
set_languages(opt.languages)
end
@@ -74,5 +80,10 @@ function configvar_check_features(definition, features, opt)
add_cxxflags(opt.cxxflags)
end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_links.lua b/xmake/includes/check_links.lua
index a17561f5e..25ddaa619 100644
--- a/xmake/includes/check_links.lua
+++ b/xmake/includes/check_links.lua
@@ -28,10 +28,12 @@
function check_links(definition, links, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_links(links)
add_defines(definition)
option_end()
+ restore_scope()
add_options(optname)
end
@@ -40,15 +42,24 @@ end
-- e.g.
--
-- configvar_check_links("HAS_PTHREAD", "pthread")
+-- configvar_check_links("HAS_PTHREAD", "pthread", {default = 0})
-- configvar_check_links("HAS_PTHREAD", {"pthread", "m", "dl"})
--
function configvar_check_links(definition, links, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_links(links)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/check_macros.lua b/xmake/includes/check_macros.lua
new file mode 100644
index 000000000..352a2382f
--- /dev/null
+++ b/xmake/includes/check_macros.lua
@@ -0,0 +1,132 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file check_macros.lua
+--
+
+-- check macros and add macro definition
+--
+-- e.g.
+--
+-- check_macros("HAS_GCC", "__GNUC__")
+-- check_macros("NO_GCC", "__GNUC__", {defined = false})
+-- check_macros("HAS_CXX20", "__cplusplus >= 202002L", {languages = "c++20"})
+--
+function check_macros(definition, macros, opt)
+ opt = opt or {}
+ local optname = "__" .. (opt.name or definition)
+ local snippets = {}
+ save_scope()
+ option(optname)
+ for _, macro in ipairs(macros) do
+ if macro:find(' ', 1, true) then
+ table.insert(snippets, ([[
+ #if %s
+ #else
+ # #error %s is not satisfied!
+ #endif
+ ]]):format(macro, macro))
+ else
+ table.insert(snippets, ([[
+ #if%s %s
+ #else
+ # #error %s is not defined!
+ #endif
+ ]]):format(opt.defined ~= false and "def" or "ndef", macro, macro))
+ end
+ end
+ if opt.languages and opt.languages:startswith("c++") then
+ add_cxxsnippets(definition, table.concat(snippets, "\n"))
+ else
+ add_csnippets(definition, table.concat(snippets, "\n"))
+ end
+ add_defines(definition)
+ if opt.languages then
+ set_languages(opt.languages)
+ end
+ if opt.cflags then
+ add_cflags(opt.cflags)
+ end
+ if opt.cxflags then
+ add_cxflags(opt.cxflags)
+ end
+ if opt.cxxflags then
+ add_cxxflags(opt.cxxflags)
+ end
+ option_end()
+ restore_scope()
+ add_options(optname)
+end
+
+-- check macros and add macro definition to the configuration files
+--
+-- e.g.
+-- configvar_check_macros("HAS_GCC", "__GNUC__")
+-- configvar_check_macros("NO_GCC", "__GNUC__", {defined = false})
+-- configvar_check_macros("HAS_CXX20", "__cplusplus >= 202002L", {languages = "c++20"})
+function configvar_check_macros(definition, macros, opt)
+ opt = opt or {}
+ local optname = "__" .. (opt.name or definition)
+ local defname, defval = table.unpack(definition:split('='))
+ local snippets = {}
+ save_scope()
+ option(optname)
+ for _, macro in ipairs(macros) do
+ if macro:find(' ', 1, true) then
+ table.insert(snippets, ([[
+ #if %s
+ #else
+ # #error %s is not satisfied!
+ #endif
+ ]]):format(macro, macro))
+ else
+ table.insert(snippets, ([[
+ #if%s %s
+ #else
+ # #error %s is not defined!
+ #endif
+ ]]):format(opt.defined ~= false and "def" or "ndef", macro, macro))
+ end
+ end
+ if opt.languages and opt.languages:startswith("c++") then
+ add_cxxsnippets(definition, table.concat(snippets, "\n"))
+ else
+ add_csnippets(definition, table.concat(snippets, "\n"))
+ end
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
+ if opt.languages then
+ set_languages(opt.languages)
+ end
+ if opt.cflags then
+ add_cflags(opt.cflags)
+ end
+ if opt.cxflags then
+ add_cxflags(opt.cxflags)
+ end
+ if opt.cxxflags then
+ add_cxxflags(opt.cxxflags)
+ end
+ option_end()
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
+end
diff --git a/xmake/includes/check_syslinks.lua b/xmake/includes/check_syslinks.lua
index 0dab1fa7f..379bb005a 100644
--- a/xmake/includes/check_syslinks.lua
+++ b/xmake/includes/check_syslinks.lua
@@ -28,10 +28,12 @@
function check_syslinks(definition, links, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
+ save_scope()
option(optname)
add_syslinks(links)
add_defines(definition)
option_end()
+ restore_scope()
add_options(optname)
end
@@ -40,15 +42,24 @@ end
-- e.g.
--
-- configvar_check_syslinks("HAS_PTHREAD", "pthread")
+-- configvar_check_syslinks("HAS_PTHREAD", "pthread", {default = 0})
-- configvar_check_syslinks("HAS_PTHREAD", {"pthread", "m", "dl"})
--
function configvar_check_syslinks(definition, links, opt)
opt = opt or {}
local optname = "__" .. (opt.name or definition)
- local defname, defval = unpack(definition:split('='))
+ local defname, defval = table.unpack(definition:split('='))
+ save_scope()
option(optname)
add_syslinks(links)
- set_configvar(defname, defval or 1)
+ if opt.default == nil then
+ set_configvar(defname, defval or 1, {quote = opt.quote})
+ end
option_end()
- add_options(optname)
+ restore_scope()
+ if opt.default == nil then
+ add_options(optname)
+ else
+ set_configvar(defname, has_config(optname) and (defval or 1) or opt.default, {quote = opt.quote})
+ end
end
diff --git a/xmake/includes/find_and_add_packages.lua b/xmake/includes/find_and_add_packages.lua
index 21aa2f783..4bcdd76f9 100644
--- a/xmake/includes/find_and_add_packages.lua
+++ b/xmake/includes/find_and_add_packages.lua
@@ -33,11 +33,13 @@
function find_and_add_packages(...)
for _, name in ipairs({...}) do
local optname = "__" .. name
+ save_scope()
option(optname)
before_check(function (option)
option:add(find_packages(name))
end)
option_end()
+ restore_scope()
add_options(optname)
end
end
diff --git a/xmake/includes/qt_add_static_plugins.lua b/xmake/includes/qt_add_static_plugins.lua
index 8ecb06056..e65965972 100644
--- a/xmake/includes/qt_add_static_plugins.lua
+++ b/xmake/includes/qt_add_static_plugins.lua
@@ -34,10 +34,10 @@ function qt_add_static_plugins(plugin, opt)
opt = opt or {}
add_values("qt.plugins", plugin)
if opt.links then
- add_values("qt.links", unpack(table.wrap(opt.links)))
+ add_values("qt.links", table.unpack(table.wrap(opt.links)))
end
if opt.linkdirs then
- add_values("qt.linkdirs", unpack(table.wrap(opt.linkdirs)))
+ add_values("qt.linkdirs", table.unpack(table.wrap(opt.linkdirs)))
end
end
diff --git a/xmake/languages/asm/xmake.lua b/xmake/languages/asm/xmake.lua
index cb9aa22f5..bdf4a4514 100644
--- a/xmake/languages/asm/xmake.lua
+++ b/xmake/languages/asm/xmake.lua
@@ -40,6 +40,7 @@ language("asm")
, "target.includedirs"
, "target.defines"
, "target.undefines"
+ , "target.runtimes"
, "toolchain.includedirs"
, "toolchain.defines"
, "toolchain.undefines"
@@ -52,6 +53,7 @@ language("asm")
, "target.rpathdirs"
, "target.strip"
, "target.symbols"
+ , "target.runtimes"
, "toolchain.linkdirs"
, "toolchain.rpathdirs"
, "config.links"
@@ -63,6 +65,7 @@ language("asm")
, "target.linkdirs"
, "target.strip"
, "target.symbols"
+ , "target.runtimes"
, "toolchain.linkdirs"
, "config.links"
, "target.links"
diff --git a/xmake/languages/c++/load.lua b/xmake/languages/c++/load.lua
index 12fb5283b..16380ab3c 100644
--- a/xmake/languages/c++/load.lua
+++ b/xmake/languages/c++/load.lua
@@ -68,7 +68,7 @@ function _api_add_cfunc(interp, module, alias, links, includes, func)
end
-- save the current scope
- local scope = interp:scope_save()
+ interp:api_builtin_save_scope()
-- check option
interp:api_call("option", name)
@@ -78,7 +78,7 @@ function _api_add_cfunc(interp, module, alias, links, includes, func)
if includes then interp:api_call("add_cincludes", includes) end
-- restore the current scope
- interp:scope_restore(scope)
+ interp:api_builtin_restore_scope()
-- add this option
interp:api_call("add_options", name)
@@ -120,7 +120,7 @@ function _api_add_cxxfunc(interp, module, alias, links, includes, func)
end
-- save the current scope
- local scope = interp:scope_save()
+ interp:api_builtin_save_scope()
-- check option
interp:api_call("option", name)
@@ -130,7 +130,7 @@ function _api_add_cxxfunc(interp, module, alias, links, includes, func)
if includes then interp:api_call("add_cxxincludes", includes) end
-- restore the current scope
- interp:scope_restore(scope)
+ interp:api_builtin_restore_scope()
-- add this option
interp:api_call("add_options", name)
diff --git a/xmake/languages/nim/load.lua b/xmake/languages/nim/load.lua
new file mode 100644
index 000000000..1e96d7c39
--- /dev/null
+++ b/xmake/languages/nim/load.lua
@@ -0,0 +1,56 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file load.lua
+--
+
+function _get_apis()
+ local apis = {}
+ apis.values = {
+ -- target.add_xxx
+ "target.add_ncflags"
+ , "target.add_ldflags"
+ , "target.add_arflags"
+ , "target.add_shflags"
+ , "target.add_rpathdirs" -- @note do not translate path, it's usually an absolute path or contains $ORIGIN/@loader_path
+ -- option.add_xxx
+ , "option.add_ncflags"
+ , "option.add_ldflags"
+ , "option.add_arflags"
+ , "option.add_shflags"
+ , "option.add_rpathdirs"
+ -- toolchain.add_xxx
+ , "toolchain.add_ncflags"
+ , "toolchain.add_ldflags"
+ , "toolchain.add_arflags"
+ , "toolchain.add_shflags"
+ , "toolchain.add_rpathdirs"
+ }
+ apis.paths = {
+ -- target.add_xxx
+ "target.add_linkdirs"
+ -- option.add_xxx
+ , "option.add_linkdirs"
+ }
+ return apis
+end
+
+function main()
+ return {apis = _get_apis()}
+end
+
+
diff --git a/xmake/languages/nim/xmake.lua b/xmake/languages/nim/xmake.lua
new file mode 100644
index 000000000..d68bec867
--- /dev/null
+++ b/xmake/languages/nim/xmake.lua
@@ -0,0 +1,87 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+language("nim")
+ add_rules("nim")
+ set_sourcekinds {nc = ".nim"}
+ set_sourceflags {nc = "ncflags"}
+ set_targetkinds {binary = "ncld", static = "ncar", shared = "ncsh"}
+ set_targetflags {binary = "ldflags", static = "arflags", shared = "shflags"}
+ set_langkinds {nim = "nc"}
+ set_mixingkinds("nc")
+
+ on_load("load")
+
+ set_nameflags {
+ object = {
+ "config.includedirs"
+ , "target.symbols"
+ , "target.warnings"
+ , "target.defines"
+ , "target.undefines"
+ , "target.optimize:check"
+ , "target.vectorexts:check"
+ , "target.includedirs"
+ , "toolchain.includedirs"
+ }
+ , binary = {
+ "config.linkdirs"
+ , "target.linkdirs"
+ , "target.rpathdirs"
+ , "target.strip"
+ , "target.symbols"
+ , "toolchain.linkdirs"
+ , "toolchain.rpathdirs"
+ , "config.links"
+ , "target.links"
+ , "toolchain.links"
+ }
+ , shared = {
+ "config.linkdirs"
+ , "target.linkdirs"
+ , "target.strip"
+ , "target.symbols"
+ , "toolchain.linkdirs"
+ , "config.links"
+ , "target.links"
+ , "toolchain.links"
+ }
+ , static = {
+ "target.strip"
+ , "target.symbols"
+ }
+ }
+
+ set_menu {
+ config =
+ {
+ {category = "Cross Complation Configuration/Compiler Configuration" }
+ , {nil, "nc", "kv", nil, "The Nim Compiler" }
+
+ , {category = "Cross Complation Configuration/Linker Configuration" }
+ , {nil, "ncld", "kv", nil, "The Nim Linker" }
+ , {nil, "ncar", "kv", nil, "The Nim Static Library Archiver" }
+ , {nil, "ncsh", "kv", nil, "The Nim Shared Library Linker" }
+
+ , {category = "Cross Complation Configuration/Builtin Flags Configuration" }
+ , {nil, "linkdirs", "kv", nil, "The Link Search Directories" }
+ }
+ }
+
diff --git a/xmake/languages/pascal/check_main.lua b/xmake/languages/pascal/check_main.lua
new file mode 100644
index 000000000..a66f70427
--- /dev/null
+++ b/xmake/languages/pascal/check_main.lua
@@ -0,0 +1,40 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file check_main.lua
+--
+
+-- check it
+function main(sourcefile)
+
+ -- load source code
+ local sourcecode = io.readfile(sourcefile)
+
+ -- remove comment first
+ sourcecode = sourcecode:gsub("{%*.-%*}", "")
+ sourcecode = sourcecode:gsub("//.-\n", "\n")
+
+ -- find 'program xxx'
+ if sourcecode:find("program%s*%(.-%)") then
+ return true
+ end
+
+ -- no main function
+ return false
+end
+
+
diff --git a/xmake/languages/pascal/load.lua b/xmake/languages/pascal/load.lua
new file mode 100644
index 000000000..6a1f1ca5b
--- /dev/null
+++ b/xmake/languages/pascal/load.lua
@@ -0,0 +1,74 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file load.lua
+--
+
+function _get_apis()
+ local apis = {}
+ apis.values = {
+ -- target.add_xxx
+ "target.add_links"
+ , "target.add_frameworks"
+ , "target.add_syslinks"
+ , "target.add_pcflags"
+ , "target.add_ldflags"
+ , "target.add_arflags"
+ , "target.add_shflags"
+ , "target.add_rpathdirs" -- @note do not translate path, it's usually an absolute path or contains $ORIGIN/@loader_path
+ -- option.add_xxx
+ , "option.add_links"
+ , "option.add_syslinks"
+ , "option.add_pcflags"
+ , "option.add_ldflags"
+ , "option.add_arflags"
+ , "option.add_shflags"
+ , "option.add_rpathdirs"
+ -- package.add_xxx
+ , "package.add_links"
+ , "package.add_syslinks"
+ , "package.add_pcflags"
+ , "package.add_ldflags"
+ , "package.add_arflags"
+ , "package.add_shflags"
+ , "package.add_rpathdirs"
+ , "package.add_linkdirs"
+ -- toolchain.add_xxx
+ , "toolchain.add_links"
+ , "toolchain.add_syslinks"
+ , "toolchain.add_pcflags"
+ , "toolchain.add_ldflags"
+ , "toolchain.add_arflags"
+ , "toolchain.add_shflags"
+ , "toolchain.add_rpathdirs"
+ , "toolchain.add_linkdirs"
+ }
+ apis.paths = {
+ -- target.add_xxx
+ "target.add_linkdirs"
+ , "target.add_frameworkdirs"
+ -- option.add_xxx
+ , "option.add_linkdirs"
+ }
+ return apis
+end
+
+function main()
+ return {apis = _get_apis()}
+end
+
+
diff --git a/xmake/languages/pascal/xmake.lua b/xmake/languages/pascal/xmake.lua
new file mode 100644
index 000000000..298b9752f
--- /dev/null
+++ b/xmake/languages/pascal/xmake.lua
@@ -0,0 +1,90 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+language("pascal")
+ add_rules("pascal")
+ set_sourcekinds {pc = {".pas", ".pp", ".ppu", ".lpr"}}
+ set_sourceflags {pc = "pcflags"}
+ set_targetkinds {binary = "pcld", shared = "pcsh"}
+ set_targetflags {binary = "ldflags", shared = "shflags"}
+ set_langkinds {pascal = "pc"}
+ set_mixingkinds("pc")
+
+ on_load("load")
+ on_check_main("check_main")
+
+ set_nameflags {
+ object = {
+ "target.symbols"
+ , "target.warnings"
+ , "target.optimize:check"
+ , "target.vectorexts:check"
+ }
+ , binary = {
+ "config.linkdirs"
+ , "target.linkdirs"
+ , "target.rpathdirs"
+ , "target.strip"
+ , "target.symbols"
+ , "toolchain.linkdirs"
+ , "toolchain.rpathdirs"
+ , "config.links"
+ , "target.links"
+ , "target.frameworks"
+ , "target.frameworkdirs"
+ , "toolchain.links"
+ , "config.syslinks"
+ , "target.syslinks"
+ , "toolchain.syslinks"
+ }
+ , shared = {
+ "config.linkdirs"
+ , "target.linkdirs"
+ , "target.strip"
+ , "target.symbols"
+ , "toolchain.linkdirs"
+ , "config.links"
+ , "target.links"
+ , "target.frameworks"
+ , "target.frameworkdirs"
+ , "toolchain.links"
+ , "config.syslinks"
+ , "target.syslinks"
+ , "toolchain.syslinks"
+ }
+ }
+
+ set_menu {
+ config =
+ {
+ {category = "Cross Complation Configuration/Compiler Configuration" }
+ , {nil, "pc", "kv", nil, "The Pascal Compiler" }
+
+ , {category = "Cross Complation Configuration/Linker Configuration" }
+ , {nil, "pcld", "kv", nil, "The Pascal Linker" }
+ , {nil, "pcsh", "kv", nil, "The Pascal Shared Library Linker" }
+
+ , {category = "Cross Complation Configuration/Builtin Flags Configuration" }
+ , {nil, "links", "kv", nil, "The Link Libraries" }
+ , {nil, "syslinks", "kv", nil, "The System Link Libraries" }
+ , {nil, "linkdirs", "kv", nil, "The Link Search Directories" }
+ }
+ }
+
diff --git a/xmake/languages/rust/xmake.lua b/xmake/languages/rust/xmake.lua
index dc6ae3d15..ea71910b7 100644
--- a/xmake/languages/rust/xmake.lua
+++ b/xmake/languages/rust/xmake.lua
@@ -25,7 +25,7 @@ language("rust")
set_targetkinds {binary = "rcld", static = "rcar", shared = "rcsh"}
set_targetflags {binary = "ldflags", static = "arflags", shared = "shflags"}
set_langkinds {rust = "rc"}
- set_mixingkinds("rc")
+ set_mixingkinds("rc", "cc", "cxx")
on_load("load")
on_check_main("check_main")
@@ -39,23 +39,58 @@ language("rust")
}
, binary = {
"config.linkdirs"
+ , "config.frameworkdirs"
, "target.linkdirs"
+ , "target.frameworkdirs"
, "target.rpathdirs"
, "target.strip"
, "target.symbols"
, "toolchain.linkdirs"
+ , "toolchain.frameworkdirs"
, "toolchain.rpathdirs"
+ , "config.frameworks"
+ , "target.frameworks"
+ , "toolchain.frameworks"
+ , "config.links"
+ , "target.links"
+ , "toolchain.links"
+ , "config.syslinks"
+ , "target.syslinks"
+ , "toolchain.syslinks"
}
, shared = {
"config.linkdirs"
+ , "config.frameworkdirs"
, "target.linkdirs"
+ , "target.frameworkdirs"
+ , "target.rpathdirs"
, "target.strip"
, "target.symbols"
, "toolchain.linkdirs"
+ , "toolchain.frameworkdirs"
+ , "toolchain.rpathdirs"
+ , "config.frameworks"
+ , "target.frameworks"
+ , "toolchain.frameworks"
+ , "config.links"
+ , "target.links"
+ , "toolchain.links"
+ , "config.syslinks"
+ , "target.syslinks"
+ , "toolchain.syslinks"
}
, static = {
- "target.strip"
+ "config.linkdirs"
+ , "config.frameworkdirs"
+ , "target.linkdirs"
+ , "target.frameworkdirs"
+ , "target.strip"
, "target.symbols"
+ , "toolchain.linkdirs"
+ , "toolchain.frameworkdirs"
+ , "config.frameworks"
+ , "target.frameworks"
+ , "toolchain.frameworks"
}
}
diff --git a/xmake/modules/cli/amalgamate.lua b/xmake/modules/cli/amalgamate.lua
new file mode 100644
index 000000000..a9835eda6
--- /dev/null
+++ b/xmake/modules/cli/amalgamate.lua
@@ -0,0 +1,108 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file amalgamate.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.config")
+import("core.project.task")
+import("core.project.project")
+
+-- the options
+local options =
+{
+ {'u', "uniqueid", "kv", nil, "Set the unique id." },
+ {'o', "outputdir", "kv", nil, "Set the output directory."},
+ {nil, "target", "v", nil, "The target name." }
+}
+
+-- generate code
+function _generate_amalgamate_code(target, opt)
+
+ -- only for library/binary
+ if not target:is_library() and not target:is_binary() then
+ return
+ end
+
+ -- generate source code
+ local outputdir = opt.outputdir
+ local uniqueid = opt.uniqueid
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind == "cc" or sourcekind == "cxx" then
+ local outputpath = path.join(outputdir, target:name() .. (sourcekind == "cxx" and ".cpp" or ".c"))
+ local outputfile = io.open(outputpath, "w")
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ if uniqueid then
+ outputfile:print("#define %s %s", uniqueid, "unity_" .. hash.uuid():split("-", {plain = true})[1])
+ end
+ outputfile:write(io.readfile(sourcefile))
+ if uniqueid then
+ outputfile:print("#undef %s", uniqueid)
+ end
+ end
+ outputfile:close()
+ cprint("${bright}%s generated!", outputpath)
+ end
+ end
+
+ -- generate header file
+ local srcheaders = target:headerfiles(includedir)
+ if srcheaders and #srcheaders > 0 then
+ local outputpath = path.join(outputdir, target:name() .. ".h")
+ local outputfile = io.open(outputpath, "w")
+ for _, srcheader in ipairs(srcheaders) do
+ if uniqueid then
+ outputfile:print("#define %s %s", uniqueid, "unity_" .. hash.uuid():split("-", {plain = true})[1])
+ end
+ outputfile:write(io.readfile(srcheader))
+ if uniqueid then
+ outputfile:print("#undef %s", uniqueid)
+ end
+ end
+ outputfile:close()
+ cprint("${bright}%s generated!", outputpath)
+ end
+end
+
+-- generate amalgamate code
+--
+-- https://github.com/xmake-io/xmake/issues/1438
+--
+function main(...)
+
+ -- parse arguments
+ local argv = table.pack(...)
+ local args = option.parse(argv, options, "Generate amalgamate code.",
+ "",
+ "Usage: xmake l cli.amalgamate [options]")
+
+ -- config first
+ task.run("config")
+
+ -- generate amalgamate code
+ args.outputdir = args.outputdir or config.buildir()
+ if args.target then
+ _generate_amalgamate_code(args.target, args)
+ else
+ for _, target in ipairs(project.ordertargets()) do
+ _generate_amalgamate_code(target, args)
+ end
+ end
+end
diff --git a/xmake/modules/core/project/depend.lua b/xmake/modules/core/project/depend.lua
index cb25db359..89a517c07 100644
--- a/xmake/modules/core/project/depend.lua
+++ b/xmake/modules/core/project/depend.lua
@@ -78,8 +78,8 @@ end
function is_changed(dependinfo, opt)
-- empty depend info? always be changed
- local files = dependinfo.files or {}
- local values = dependinfo.values or {}
+ local files = table.wrap(dependinfo.files)
+ local values = table.wrap(dependinfo.values)
if #files == 0 and #values == 0 then
return true
end
@@ -102,7 +102,7 @@ function is_changed(dependinfo, opt)
-- check the dependent values are changed?
local depvalues = values
- local optvalues = opt.values or {}
+ local optvalues = table.wrap(opt.values)
if #depvalues ~= #optvalues then
return true
end
@@ -124,8 +124,11 @@ function is_changed(dependinfo, opt)
end
-- check the dependent files list are changed?
- local optfiles = opt.files
- if optfiles then
+ if opt.files then
+ local optfiles = table.wrap(opt.files)
+ if #files ~= #optfiles then
+ return true
+ end
for idx, file in ipairs(files) do
if file ~= optfiles[idx] then
return true
@@ -178,7 +181,7 @@ function on_changed(callback, opt)
-- need build this object?
-- @note we use mtime(dependfile) instead of mtime(objectfile) to ensure the object file is is fully compiled.
-- @see https://github.com/xmake-io/xmake/issues/748
- if not is_changed(dependinfo, {lastmtime = opt.lastmtime or os.mtime(dependfile), values = opt.values}) then
+ if not is_changed(dependinfo, {lastmtime = opt.lastmtime or os.mtime(dependfile), values = opt.values, files = opt.files}) then
return
end
diff --git a/xmake/modules/core/tools/ar.lua b/xmake/modules/core/tools/ar.lua
index dc858a19e..0496238b4 100644
--- a/xmake/modules/core/tools/ar.lua
+++ b/xmake/modules/core/tools/ar.lua
@@ -20,7 +20,7 @@
-- imports
import("core.tool.compiler")
-import("private.utils.progress")
+import("utils.progress")
-- init it
function init(self)
@@ -30,42 +30,26 @@ end
-- make the strip flag
function strip(self, level)
-
- -- the maps
local maps =
{
debug = "-S"
, all = "-s"
}
-
- -- make it
return maps[level]
end
-- make the link arguments list
function linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
-
- -- check
- assert(targetkind == "static")
-
- -- init arguments
opt = opt or {}
local argv = table.join(flags, targetfile, objectfiles)
if is_host("windows") and not opt.rawargs then
argv = winos.cmdargv(argv, {escape = true})
end
-
- -- make it
return self:program(), argv
end
-- link the library file
function link(self, objectfiles, targetkind, targetfile, flags)
-
- -- check
- assert(targetkind == "static", "the target kind: %s is not support for ar", targetkind)
-
- -- ensure the target directory
os.mkdir(path.directory(targetfile))
-- @note remove the previous archived file first to force recreating a new file
diff --git a/xmake/modules/core/tools/armar.lua b/xmake/modules/core/tools/armar.lua
new file mode 100644
index 000000000..66740c11a
--- /dev/null
+++ b/xmake/modules/core/tools/armar.lua
@@ -0,0 +1,26 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file armar.lua
+--
+
+inherit("ar")
+
+function init(self)
+ _super.init(self)
+end
+
diff --git a/xmake/modules/core/tools/armasm.lua b/xmake/modules/core/tools/armasm.lua
new file mode 100644
index 000000000..3ae578c55
--- /dev/null
+++ b/xmake/modules/core/tools/armasm.lua
@@ -0,0 +1,179 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file armasm.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.global")
+import("core.language.language")
+import("utils.progress")
+
+-- init it
+function init(self)
+end
+
+-- make the symbol flag
+function nf_symbol(self, level)
+ -- only for source kind
+ local kind = self:kind()
+ if language.sourcekinds()[kind] then
+ local maps = _g.symbol_maps
+ if not maps then
+ maps =
+ {
+ debug = "-g"
+ }
+ _g.symbol_maps = maps
+ end
+ return maps[level .. '_' .. kind] or maps[level]
+ end
+end
+
+-- make the optimize flag
+function nf_optimize(self, level)
+ local maps =
+ {
+ none = "-O0"
+ , fast = "-O1"
+ , faster = "-O2"
+ , fastest = "-O3"
+ , smallest = "-Os"
+ , aggressive = "-Ofast"
+ }
+ return maps[level]
+end
+
+-- make the language flag
+function nf_language(self, stdname)
+
+ -- the stdc maps
+ if _g.cmaps == nil then
+ _g.cmaps =
+ {
+ ansi = "-c89"
+ , c89 = "-c89"
+ , gnu89 = "-c89"
+ , c99 = "-c99"
+ , gnu99 = "-c99"
+ , c11 = "-c11"
+ , gnu11 = "-c11"
+ , clatest = {"-c11", "-c99", "-c89"}
+ , gnulatest = {"-c11", "-c99", "-c89"}
+ }
+ end
+ local maps = _g.cmaps
+ local result = maps[stdname]
+ if type(result) == "table" then
+ for _, v in ipairs(result) do
+ if self:has_flags(v, "cxflags") then
+ result = v
+ maps[stdname] = result
+ return result
+ end
+ end
+ else
+ return result
+ end
+end
+
+-- make runtime flag
+function nf_runtime(self, runtime)
+ if runtime == "microlib" then
+ return {"--pd", "__MICROLIB SETA 1"}
+ end
+end
+
+-- make the define flag
+function nf_define(self, macro)
+ return {"--pd", macro .. " SETA 1"}
+end
+
+-- make the includedir flag
+function nf_includedir(self, dir)
+ return {"-I" .. dir}
+end
+
+-- make the sysincludedir flag
+function nf_sysincludedir(self, dir)
+ return nf_includedir(self, dir)
+end
+
+-- make the compile arguments list
+function compargv(self, sourcefile, objectfile, flags)
+ return self:program(), table.join(flags, "-o", objectfile, sourcefile)
+end
+
+-- compile the source file
+function compile(self, sourcefile, objectfile, dependinfo, flags)
+
+ -- ensure the object directory
+ os.mkdir(path.directory(objectfile))
+
+ -- compile it
+ try
+ {
+ function ()
+ local outdata, errdata = os.iorunv(compargv(self, sourcefile, objectfile, flags))
+ return (outdata or "") .. (errdata or "")
+ end,
+ catch
+ {
+ function (errors)
+
+ -- try removing the old object file for forcing to rebuild this source file
+ os.tryrm(objectfile)
+
+ -- find the start line of error
+ local lines = tostring(errors):split("\n")
+ local start = 0
+ for index, line in ipairs(lines) do
+ if line:find("error:", 1, true) or line:find("错误:", 1, true) then
+ start = index
+ break
+ end
+ end
+
+ -- get 16 lines of errors
+ if start > 0 or not option.get("verbose") then
+ if start == 0 then start = 1 end
+ errors = table.concat(table.slice(lines, start, start + ((#lines - start > 16) and 16 or (#lines - start))), "\n")
+ end
+
+ -- raise compiling errors
+ raise(errors)
+ end
+ },
+ finally
+ {
+ function (ok, warnings)
+
+ -- print some warnings
+ if warnings and #warnings > 0 and (option.get("verbose") or option.get("warning") or global.get("build_warning")) then
+ if progress.showing_without_scroll() then
+ print("")
+ end
+ cprint("${color.warning}%s", table.concat(table.slice(warnings:split('\n'), 1, 8), '\n'))
+ end
+ end
+ }
+ }
+end
+
+
+
diff --git a/xmake/modules/core/tools/armcc.lua b/xmake/modules/core/tools/armcc.lua
new file mode 100644
index 000000000..403e143f0
--- /dev/null
+++ b/xmake/modules/core/tools/armcc.lua
@@ -0,0 +1,183 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file armcc.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.global")
+import("core.language.language")
+import("utils.progress")
+
+-- init it
+function init(self)
+end
+
+-- make the symbol flag
+function nf_symbol(self, level)
+ -- only for source kind
+ local kind = self:kind()
+ if language.sourcekinds()[kind] then
+ local maps = _g.symbol_maps
+ if not maps then
+ maps =
+ {
+ debug = "-g"
+ }
+ _g.symbol_maps = maps
+ end
+ return maps[level .. '_' .. kind] or maps[level]
+ end
+end
+
+-- make runtime flag
+function nf_runtime(self, runtime)
+ if runtime == "microlib" then
+ return "-D__MICROLIB"
+ end
+end
+
+-- make the optimize flag
+function nf_optimize(self, level)
+ local maps =
+ {
+ none = "-O0"
+ , fast = "-O1"
+ , faster = "-O2"
+ , fastest = "-O3"
+ , smallest = "-Os"
+ , aggressive = "-Ofast"
+ }
+ return maps[level]
+end
+
+-- make the language flag
+function nf_language(self, stdname)
+
+ -- the stdc maps
+ if _g.cmaps == nil then
+ _g.cmaps =
+ {
+ ansi = "-c89"
+ , c89 = "-c89"
+ , gnu89 = "-c89"
+ , c99 = "-c99"
+ , gnu99 = "-c99"
+ , c11 = "-c11"
+ , gnu11 = "-c11"
+ , clatest = {"-c11", "-c99", "-c89"}
+ , gnulatest = {"-c11", "-c99", "-c89"}
+ }
+ end
+ local maps = _g.cmaps
+ local result = maps[stdname]
+ if type(result) == "table" then
+ for _, v in ipairs(result) do
+ if self:has_flags(v, "cxflags") then
+ result = v
+ maps[stdname] = result
+ return result
+ end
+ end
+ else
+ return result
+ end
+end
+
+-- make the define flag
+function nf_define(self, macro)
+ return "-D" .. macro
+end
+
+-- make the undefine flag
+function nf_undefine(self, macro)
+ return "-U" .. macro
+end
+
+-- make the includedir flag
+function nf_includedir(self, dir)
+ return {"-I" .. dir}
+end
+
+-- make the sysincludedir flag
+function nf_sysincludedir(self, dir)
+ return nf_includedir(self, dir)
+end
+
+-- make the compile arguments list
+function compargv(self, sourcefile, objectfile, flags)
+ return self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)
+end
+
+-- compile the source file
+function compile(self, sourcefile, objectfile, dependinfo, flags)
+
+ -- ensure the object directory
+ os.mkdir(path.directory(objectfile))
+
+ -- compile it
+ try
+ {
+ function ()
+ local outdata, errdata = os.iorunv(compargv(self, sourcefile, objectfile, flags))
+ return (outdata or "") .. (errdata or "")
+ end,
+ catch
+ {
+ function (errors)
+
+ -- try removing the old object file for forcing to rebuild this source file
+ os.tryrm(objectfile)
+
+ -- find the start line of error
+ local lines = tostring(errors):split("\n")
+ local start = 0
+ for index, line in ipairs(lines) do
+ if line:find("error:", 1, true) or line:find("错误:", 1, true) then
+ start = index
+ break
+ end
+ end
+
+ -- get 16 lines of errors
+ if start > 0 or not option.get("verbose") then
+ if start == 0 then start = 1 end
+ errors = table.concat(table.slice(lines, start, start + ((#lines - start > 16) and 16 or (#lines - start))), "\n")
+ end
+
+ -- raise compiling errors
+ raise(errors)
+ end
+ },
+ finally
+ {
+ function (ok, warnings)
+
+ -- print some warnings
+ if warnings and #warnings > 0 and (option.get("verbose") or option.get("warning") or global.get("build_warning")) then
+ if progress.showing_without_scroll() then
+ print("")
+ end
+ cprint("${color.warning}%s", table.concat(table.slice(warnings:split('\n'), 1, 8), '\n'))
+ end
+ end
+ }
+ }
+end
+
+
diff --git a/xmake/modules/core/tools/armclang.lua b/xmake/modules/core/tools/armclang.lua
new file mode 100644
index 000000000..dcec82015
--- /dev/null
+++ b/xmake/modules/core/tools/armclang.lua
@@ -0,0 +1,32 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file armclang.lua
+--
+
+inherit("gcc")
+
+function init(self)
+ _super.init(self)
+end
+
+-- make runtime flag
+function nf_runtime(self, runtime)
+ if runtime == "microlib" then
+ return "-D__MICROLIB"
+ end
+end
diff --git a/xmake/modules/core/tools/armlink.lua b/xmake/modules/core/tools/armlink.lua
new file mode 100644
index 000000000..e25a81967
--- /dev/null
+++ b/xmake/modules/core/tools/armlink.lua
@@ -0,0 +1,61 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file armlink.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.global")
+import("utils.progress")
+
+function init(self)
+end
+
+-- make the link flag
+function nf_link(self, lib)
+ return "lib" .. lib .. ".a"
+end
+
+-- make the syslink flag
+function nf_syslink(self, lib)
+ return nf_link(self, lib)
+end
+
+-- make the linkdir flag
+function nf_linkdir(self, dir)
+ return {"--userlibpath", dir}
+end
+
+-- make runtime flag
+function nf_runtime(self, runtime)
+ if runtime == "microlib" then
+ return "--library_type=microlib"
+ end
+end
+
+-- make the link arguments list
+function linkargv(self, objectfiles, targetkind, targetfile, flags)
+ return self:program(), table.join("-o", targetfile, objectfiles, flags)
+end
+
+-- link the target file
+function link(self, objectfiles, targetkind, targetfile, flags)
+ os.mkdir(path.directory(targetfile))
+ os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
+end
+
diff --git a/xmake/modules/core/tools/circle.lua b/xmake/modules/core/tools/circle.lua
new file mode 100644
index 000000000..fcf567549
--- /dev/null
+++ b/xmake/modules/core/tools/circle.lua
@@ -0,0 +1,34 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file circle.lua
+--
+
+inherit("gcc")
+
+function init(self)
+ _super.init(self)
+end
+
+function nf_strip(self, level)
+ local maps =
+ {
+ debug = "-Wl,-S"
+ , all = "-Wl,-s"
+ }
+ return maps[level]
+end
diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index d95d58e5d..b76061cd7 100644
--- a/xmake/modules/core/tools/cl.lua
+++ b/xmake/modules/core/tools/cl.lua
@@ -26,7 +26,7 @@ import("core.project.project")
import("core.language.language")
import("private.tools.vstool")
import("private.tools.cl.parse_include")
-import("private.utils.progress")
+import("utils.progress")
-- init it
function init(self)
@@ -34,12 +34,6 @@ function init(self)
-- init cxflags
self:set("cxflags", "-nologo")
- -- we need show full file path to goto error position if xmake is called in vstudio
- -- https://github.com/xmake-io/xmake/issues/1049
- if os.getenv("XMAKE_IN_VSTUDIO") then
- self:add("cxflags", "-FC")
- end
-
-- init flags map
self:set("mapflags",
{
@@ -62,6 +56,8 @@ function init(self)
, ["-W2"] = "-W2"
, ["-W3"] = "-W3"
, ["-Werror"] = "-WX"
+ , ["-Wswitch"] = "-we4062"
+ , ["-Wswitch-enum"] = "-we4061"
, ["%-Wno%-error=.*"] = ""
, ["%-fno%-.*"] = ""
@@ -116,7 +112,7 @@ function nf_symbols(self, levels, target)
end
-- check and add symbol output file
- local pdbflags = "-Fd" .. path.join(symboldir, "compile." .. path.filename(symbolfile))
+ local pdbflags = "-Fd" .. (target:is_static() and symbolfile or path.join(symboldir, "compile." .. path.filename(symbolfile)))
if self:has_flags({"-FS", "-Fd" .. os.nuldev() .. ".pdb"}, "cxflags", { flagskey = "-FS -Fd" }) then
pdbflags = {"-FS", pdbflags}
end
@@ -197,12 +193,14 @@ function nf_language(self, stdname)
_g.cmaps =
{
-- stdc
- c99 = "-TP" -- compile as c++ files because older msvc only support c89
- , gnu99 = "-TP"
- , c11 = {"-std:c11", "-TP"}
- , gnu11 = {"-std:c11", "-TP"}
- , c17 = {"-std:c17", "-TP"}
- , gnu17 = {"-std:c17", "-TP"}
+ c99 = "-TP" -- compile as c++ files because older msvc only support c89
+ , gnu99 = "-TP"
+ , c11 = {"-std:c11", "-TP"}
+ , gnu11 = {"-std:c11", "-TP"}
+ , c17 = {"-std:c17", "-TP"}
+ , gnu17 = {"-std:c17", "-TP"}
+ , clatest = {"-std:c17", "-std:c11"}
+ , gnulatest = {"-std:c17", "-std:c11"}
}
end
@@ -222,6 +220,8 @@ function nf_language(self, stdname)
, gnuxx20 = {"-std:c++20", "-std:c++latest"}
, cxx2a = {"-std:c++20", "-std:c++latest"}
, gnuxx2a = {"-std:c++20", "-std:c++latest"}
+ , cxxlatest = "-std:c++latest"
+ , gnuxxlatest = "-std:c++latest"
}
local cxxmaps2 = {}
for k, v in pairs(_g.cxxmaps) do
@@ -237,13 +237,17 @@ function nf_language(self, stdname)
end
-- map it
- local flags = maps[stdname]
- if flags then
- for _, flag in ipairs(table.wrap(flags)) do
- if self:has_flags(flag, "cxflags") then
- return flag
+ local result = maps[stdname]
+ if type(result) == "table" then
+ for _, v in ipairs(result) do
+ if self:has_flags(v, "cxflags") then
+ result = v
+ maps[stdname] = result
+ return result
end
end
+ else
+ return result
end
end
@@ -266,13 +270,17 @@ end
function nf_sysincludedir(self, dir)
local has_external_includedir = _g._HAS_EXTERNAL_INCLUDEDIR
if has_external_includedir == nil then
- if self:has_flags({"-experimental:external", "-external:W0", "-external:I" .. os.args(path.translate(dir))}, "cxflags", {flagskey = "cl_external_includedir"}) then
- has_external_includedir = true
+ if self:has_flags({"-external:W0", "-external:I" .. os.args(path.translate(dir))}, "cxflags", {flagskey = "cl_external_includedir"}) then
+ has_external_includedir = 2 -- full support
+ elseif self:has_flags({"-experimental:external", "-external:W0", "-external:I" .. os.args(path.translate(dir))}, "cxflags", {flagskey = "cl_external_includedir_experimental"}) then
+ has_external_includedir = 1 -- experimental support
end
- has_external_includedir = has_external_includedir or false
+ has_external_includedir = has_external_includedir or 0
_g._HAS_EXTERNAL_INCLUDEDIR = has_external_includedir
end
- if has_external_includedir then
+ if has_external_includedir >= 2 then
+ return {"-external:W0", "-external:I" .. path.translate(dir)}
+ elseif has_external_includedir >= 1 then
return {"-experimental:external", "-external:W0", "-external:I" .. path.translate(dir)}
else
return nf_includedir(self, dir)
@@ -371,6 +379,15 @@ function _has_source_dependencies(self)
return has_source_dependencies
end
+function _is_in_vstudio()
+ local is_in_vstudio = _g._IS_IN_VSTUDIO
+ if is_in_vstudio == nil then
+ is_in_vstudio = os.getenv("XMAKE_IN_VSTUDIO") or false
+ _g._IS_IN_VSTUDIO = is_in_vstudio
+ end
+ return is_in_vstudio
+end
+
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags, opt)
@@ -403,6 +420,7 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate includes file
local compflags = flags
+
if dependinfo then
if _has_source_dependencies(self) then
depfile = os.tmpfile()
@@ -412,6 +430,16 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
end
end
+ -- we need show full file path to goto error position if xmake is called in vstudio
+ -- https://github.com/xmake-io/xmake/issues/1049
+ if _is_in_vstudio() then
+ if compflags == flags then
+ compflags = table.join(flags, "-FC")
+ else
+ table.join2(compflags, "-FC")
+ end
+ end
+
-- use vstool to compile and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528
local program, argv = compargv(self, sourcefile, objectfile, compflags, opt)
return vstool.iorunv(program, argv, {envs = self:runenvs()})
@@ -444,7 +472,10 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
end
end
end
- os.raise(results)
+ if not option.get("verbose") then
+ results = results .. "\n ${yellow}> in ${bright}" .. sourcefile
+ end
+ raise(results)
end
},
finally
@@ -466,7 +497,10 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
end
end
if #lines > 0 then
- local warnings = table.concat(table.slice(lines, 1, (#lines > 8 and 8 or #lines)), "\r\n")
+ if not option.get("diagnosis") then
+ lines = table.slice(lines, 1, (#lines > 16 and 16 or #lines))
+ end
+ local warnings = table.concat(lines, "\r\n")
if progress.showing_without_scroll() then
print("")
end
@@ -488,4 +522,3 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
end
end
end
-
diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua
index a0d39f3b4..e5734a953 100644
--- a/xmake/modules/core/tools/clang.lua
+++ b/xmake/modules/core/tools/clang.lua
@@ -124,3 +124,16 @@ function nf_warning(self, level)
}
return maps[level]
end
+
+-- make the symbol flag
+function nf_symbol(self, level)
+ local kind = self:kind()
+ if kind == "ld" or kind == "sh" then
+ -- clang/windows need add `-g` to linker to generate pdb symbol file
+ if self:plat() == "windows" and level == "debug" then
+ return "-g"
+ end
+ else
+ return _super.nf_symbol(self, level)
+ end
+end
diff --git a/xmake/modules/core/tools/clang_cl.lua b/xmake/modules/core/tools/clang_cl.lua
index 4e0046fe8..9c4236343 100644
--- a/xmake/modules/core/tools/clang_cl.lua
+++ b/xmake/modules/core/tools/clang_cl.lua
@@ -117,6 +117,10 @@ function nf_language(self, stdname)
, gnu99 = "-Xclang -std=gnu99"
, c11 = "-Xclang -std=c11"
, gnu11 = "-Xclang -std=gnu11"
+ , c17 = "-Xclang -std=c17"
+ , gnu17 = "-Xclang -std=gnu17"
+ , clatest = "-Xclang -std=c17"
+ , gnulatest = "-Xclang -std=gnu17"
}
end
@@ -134,10 +138,12 @@ function nf_language(self, stdname)
, gnuxx17 = "-Xclang -std=gnu++17"
, cxx1z = "-Xclang -std=c++1z"
, gnuxx1z = "-Xclang -std=gnu++1z"
- , cxx20 = "-Xclang -std=c++2a"
- , gnuxx20 = "-Xclang -std=gnu++2a"
+ , cxx20 = "-Xclang -std=c++20"
+ , gnuxx20 = "-Xclang -std=gnu++20"
, cxx2a = "-Xclang -std=c++2a"
, gnuxx2a = "-Xclang -std=gnu++2a"
+ , cxxlatest = "-Xclang -std=c++latest"
+ , gnuxxlatest = "-Xclang -std=gnu++latest"
}
local cxxmaps2 = {}
for k, v in pairs(_g.cxxmaps) do
diff --git a/xmake/modules/core/tools/dmd.lua b/xmake/modules/core/tools/dmd.lua
index 2a9d860e1..3f29da28f 100644
--- a/xmake/modules/core/tools/dmd.lua
+++ b/xmake/modules/core/tools/dmd.lua
@@ -146,11 +146,7 @@ end
-- link the target file
function link(self, objectfiles, targetkind, targetfile, flags)
-
- -- ensure the target directory
os.mkdir(path.directory(targetfile))
-
- -- link it
os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
end
@@ -161,11 +157,7 @@ end
-- compile the source file
function compile(self, sourcefile, objectfile, dependinfo, flags)
-
- -- ensure the object directory
os.mkdir(path.directory(objectfile))
-
- -- compile it
os.runv(compargv(self, sourcefile, objectfile, flags))
end
diff --git a/xmake/modules/core/tools/fpc.lua b/xmake/modules/core/tools/fpc.lua
new file mode 100644
index 000000000..98b746c8a
--- /dev/null
+++ b/xmake/modules/core/tools/fpc.lua
@@ -0,0 +1,110 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file fpc.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.config")
+import("core.project.project")
+
+-- init it
+function init(self)
+ if not is_plat("windows", "mingw") then
+ self:add("shared.pcflags", "-Cg")
+ end
+end
+
+-- make the optimize flag
+function nf_optimize(self, level)
+ local maps =
+ {
+ none = "-O-"
+ , fast = "-O1"
+ , fastest = "-O3"
+ , smallest = "-O2"
+ , aggressive = "-O4"
+ }
+ return maps[level]
+end
+
+-- make the strip flag
+function nf_strip(self, level)
+ if level == "all" then
+ return "-Xs"
+ end
+end
+
+-- make the symbol flag
+function nf_symbol(self, level)
+ if level == "debug" and self:kind() == "pc" then
+ if self:plat() == "windows" then
+ return {"-gw3", "-WN"}
+ else
+ return "-gw3"
+ end
+ end
+end
+
+-- make the link flag
+function nf_link(self, lib)
+ return "-k-l" .. lib
+end
+
+-- make the syslink flag
+function nf_syslink(self, lib)
+ return nf_link(self, lib)
+end
+
+-- make the linkdir flag
+function nf_linkdir(self, dir)
+ return {"-k-L" .. dir}
+end
+
+-- make the rpathdir flag
+function nf_rpathdir(self, dir)
+ dir = path.translate(dir)
+ if self:has_flags("-k-rpath=" .. dir, "ldflags") then
+ return {"-k-rpath=" .. (dir:gsub("@[%w_]+", function (name)
+ local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"}
+ return maps[name]
+ end))}
+ end
+end
+
+-- make the framework flag
+function nf_framework(self, framework)
+ return {"-k-framework", framework}
+end
+
+-- make the frameworkdir flag
+function nf_frameworkdir(self, frameworkdir)
+ return {"-k-F", path.translate(frameworkdir)}
+end
+
+-- make the build arguments list
+function buildargv(self, sourcefiles, targetkind, targetfile, flags)
+ return self:program(), table.join(flags, "-o" .. targetfile, sourcefiles)
+end
+
+-- build the target file
+function build(self, sourcefiles, targetkind, targetfile, flags)
+ os.mkdir(path.directory(targetfile))
+ os.runv(buildargv(self, sourcefiles, targetkind, targetfile, flags))
+end
+
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 89b732ec9..40d3b8a4e 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -27,7 +27,7 @@ import("core.project.config")
import("core.project.project")
import("core.language.language")
import("private.tools.ccache")
-import("private.utils.progress")
+import("utils.progress")
-- init it
function init(self)
@@ -42,7 +42,11 @@ function init(self)
self:set("shflags", "-shared")
-- add -fPIC for shared
- if not is_plat("windows", "mingw") then
+ --
+ -- we need check it for clang/gcc with window target
+ -- @see https://github.com/xmake-io/xmake/issues/1392
+ --
+ if not is_plat("windows", "mingw") and self:has_flags("-fPIC", "cxflags") then
self:add("shflags", "-fPIC")
self:add("shared.cxflags", "-fPIC")
end
@@ -72,13 +76,13 @@ function init(self)
end
-- make the strip flag
-function nf_strip(self, level)
+function nf_strip(self, level, target)
local maps =
{
debug = "-Wl,-S"
, all = "-s"
}
- if is_plat("macosx") or is_plat("iphoneos") then
+ if target:is_plat("macosx") or target:is_plat("iphoneos") then
maps.all = "-Wl,-x"
end
return maps[level]
@@ -113,8 +117,8 @@ function nf_warning(self, level)
, less = "-Wall"
, more = "-Wall"
, all = "-Wall"
- , allextra = "-Wall -Wextra"
- , everything = "-Wall -Wextra -Weffc++"
+ , allextra = {"-Wall", "-Wextra"}
+ , everything = self:kind() == "cxx" and {"-Wall", "-Wextra", "-Weffc++"} or {"-Wall", "-Wextra"}
, error = "-Werror"
}
return maps[level]
@@ -180,6 +184,8 @@ function nf_language(self, stdname)
, gnu11 = "-std=gnu11"
, c17 = "-std=c17"
, gnu17 = "-std=gnu17"
+ , clatest = {"-std=c17", "-std=c11", "-std=c99", "-std=c89", "-ansi"}
+ , gnulatest = {"-std=gnu17", "-std=gnu11", "-std=gnu99", "-std=gnu89", "-ansi"}
}
end
@@ -197,10 +203,12 @@ function nf_language(self, stdname)
, gnuxx17 = "-std=gnu++17"
, cxx1z = "-std=c++1z"
, gnuxx1z = "-std=gnu++1z"
- , cxx20 = "-std=c++2a"
- , gnuxx20 = "-std=gnu++2a"
+ , cxx20 = {"-std=c++20", "-std=c++2a"}
+ , gnuxx20 = {"-std=gnu++20", "-std=c++2a"}
, cxx2a = "-std=c++2a"
, gnuxx2a = "-std=gnu++2a"
+ , cxxlatest = {"-std=c++20", "-std=c++2a", "-std=c++17", "-std=c++14", "-std=c++11", "-std=c++1z", "-std=c++98"}
+ , gnuxxlatest = {"-std=gnu++20", "-std=gnu++2a", "-std=gnu++17", "-std=gnu++14", "-std=gnu++11", "-std=c++1z", "-std=gnu++98"}
}
local cxxmaps2 = {}
for k, v in pairs(_g.cxxmaps) do
@@ -216,9 +224,18 @@ function nf_language(self, stdname)
elseif self:kind() == "sc" then
maps = {}
end
-
- -- make it
- return maps[stdname]
+ local result = maps[stdname]
+ if type(result) == "table" then
+ for _, v in ipairs(result) do
+ if self:has_flags(v, "cxflags") then
+ result = v
+ maps[stdname] = result
+ return result
+ end
+ end
+ else
+ return result
+ end
end
-- make the define flag
@@ -276,7 +293,7 @@ end
-- make the frameworkdir flag
function nf_frameworkdir(self, frameworkdir)
- return {"-F", path.translate(frameworkdir)}
+ return {"-F" .. path.translate(frameworkdir)}
end
-- make the c precompiled header flag
@@ -334,7 +351,7 @@ function linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
-- add `-Wl,--out-implib,outputdir/libxxx.a` for xxx.dll on mingw/gcc
if targetkind == "shared" and is_plat("mingw") then
- table.insert(flags_extra, "-Wl,--out-implib," .. path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib"))
+ table.insert(flags_extra, "-Wl,--out-implib," .. path.join(path.directory(targetfile), path.basename(targetfile) .. ".dll.a"))
end
-- init arguments
@@ -408,7 +425,6 @@ end
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags)
-
-- precompiled header?
local extension = path.extension(sourcefile)
if (extension:startswith(".h") or extension == ".inl") then
@@ -478,7 +494,12 @@ function compile(self, sourcefile, objectfile, dependinfo, flags)
end
-- raise compiling errors
- raise(#lines > 0 and table.concat(lines, "\n") or "")
+ local results = #lines > 0 and table.concat(lines, "\n") or ""
+ if not option.get("verbose") then
+ results = results .. "\n ${yellow}> in ${bright}" .. sourcefile
+ end
+ raise(results)
+
end
},
finally
@@ -488,7 +509,10 @@ function compile(self, sourcefile, objectfile, dependinfo, flags)
if ok and errdata and #errdata > 0 and (option.get("diagnosis") or option.get("warning") or global.get("build_warning")) then
local lines = errdata:split('\n', {plain = true})
if #lines > 0 then
- local warnings = table.concat(table.slice(lines, 1, (#lines > 8 and 8 or #lines)), "\n")
+ if not option.get("diagnosis") then
+ lines = table.slice(lines, 1, (#lines > 16 and 16 or #lines))
+ end
+ local warnings = table.concat(lines, "\n")
if progress.showing_without_scroll() then
print("")
end
diff --git a/xmake/modules/core/tools/go.lua b/xmake/modules/core/tools/go.lua
index fbd046cf0..2b2b76623 100644
--- a/xmake/modules/core/tools/go.lua
+++ b/xmake/modules/core/tools/go.lua
@@ -25,56 +25,34 @@ import("core.project.project")
-- init it
function init(self)
-
- -- init arflags
self:set("gcarflags", "grc")
-
- -- init the file formats
- self:set("formats", { static = "$(name).a" })
end
-- make the optimize flag
function nf_optimize(self, level)
-
- -- the maps
- local maps =
- {
+ local maps = {
none = "-N"
}
-
- -- make it
return maps[level]
end
-- make the symbol flag
function nf_symbol(self, level, target, mapkind)
-
- -- only for compiler
if mapkind ~= "object" then
return
end
-
- -- the maps
- local maps =
- {
+ local maps = {
debug = "-E"
}
-
- -- make it
return maps[level]
end
-- make the strip flag
function nf_strip(self, level)
-
- -- the maps
- local maps =
- {
+ local maps = {
debug = "-s"
, all = "-s"
}
-
- -- make it
return maps[level]
end
@@ -95,8 +73,6 @@ end
-- make the link arguments list
function linkargv(self, objectfiles, targetkind, targetfile, flags)
-
- -- make it
if targetkind == "static" then
return self:program(), table.join("tool", "pack", flags, targetfile, objectfiles)
else
@@ -106,11 +82,7 @@ end
-- link the target file
function link(self, objectfiles, targetkind, targetfile, flags)
-
- -- ensure the target directory
os.mkdir(path.directory(targetfile))
-
- -- link it
local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags)
os.runv(program, argv, {envs = self:runenvs()})
end
@@ -122,11 +94,7 @@ end
-- compile the source file
function compile(self, sourcefiles, objectfile, dependinfo, flags)
-
- -- ensure the object directory
os.mkdir(path.directory(objectfile))
-
- -- compile it
local program, argv = compargv(self, sourcefiles, objectfile, flags)
os.runv(program, argv, {envs = self:runenvs()})
end
diff --git a/xmake/modules/core/tools/ml.lua b/xmake/modules/core/tools/ml.lua
index 83da11fb6..59749974c 100644
--- a/xmake/modules/core/tools/ml.lua
+++ b/xmake/modules/core/tools/ml.lua
@@ -20,6 +20,7 @@
-- imports
import("private.tools.vstool")
+import("core.base.hashset")
-- init it
--
@@ -28,11 +29,7 @@ import("private.tools.vstool")
function init(self)
-- init asflags
- if self:program():find("64") then
- self:set("asflags", "-nologo")
- else
- self:set("asflags", "-nologo", "-Gd")
- end
+ self:set("asflags", "-nologo")
-- init flags map
self:set("mapflags",
@@ -57,10 +54,25 @@ function init(self)
})
end
+-- make the symbol flags
+function nf_symbols(self, levels, target)
+ local flags = nil
+ local values = hashset.from(levels)
+ if values:has("debug") then
+ flags = {}
+ if values:has("edit") then
+ table.insert(flags, "-ZI")
+ elseif values:has("embed") then
+ table.insert(flags, "-Z7")
+ else
+ table.insert(flags, "-Zi")
+ end
+ end
+ return flags
+end
+
-- make the warning flag
function nf_warning(self, level)
-
- -- the maps
local maps =
{
none = "-w"
@@ -70,8 +82,6 @@ function nf_warning(self, level)
, everything = "-W3"
, error = "-WX"
}
-
- -- make it
return maps[level]
end
@@ -97,6 +107,21 @@ end
-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags)
+ -- we need to set the default -Gd option for the x86 architecture,
+ -- if the other calling convention flags are not set
+ --
+ -- we can't directly remove -Gd. This is not only for backward compatibility,
+ -- but also to simplify mixed compilation with c programs.
+ --
+ -- although this may affect some performance,
+ -- it only takes effect under x86 asm, so there will be no major performance issues.
+ --
+ -- @see https://github.com/xmake-io/xmake/issues/1779
+ --
+ if not self:program():find("64", 1, true) and
+ not table.contains(flags, "-Gc", "/Gc", "-GZ", "/GZ") then
+ table.insert(flags, "-Gd")
+ end
return self:program(), table.join("-c", flags, "-Fo" .. objectfile, sourcefile)
end
diff --git a/xmake/modules/core/tools/nim.lua b/xmake/modules/core/tools/nim.lua
new file mode 100644
index 000000000..0eece46cf
--- /dev/null
+++ b/xmake/modules/core/tools/nim.lua
@@ -0,0 +1,161 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file nim.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.config")
+import("core.project.project")
+
+-- init it
+--
+-- @see https://nim-lang.org/docs/nimc.html
+function init(self)
+
+ -- init arflags
+ self:set("ncarflags", "--app:staticlib", "--noMain")
+
+ -- init shflags
+ self:set("ncshflags", "--app:lib", "--noMain")
+end
+
+-- make the warning flag
+function nf_warning(self, level)
+ local maps =
+ {
+ none = "--warning:X:off"
+ , less = "--warning:X:on"
+ , more = "--warning:X:on"
+ , all = "--warning:X:on"
+ , allextra = "--warning:X:on"
+ , everything = "--warning:X:on"
+ , error = "--warningAsError:X:on"
+ }
+ return maps[level]
+end
+
+-- make the define flag
+function nf_define(self, macro)
+ return "--define:" .. macro
+end
+
+-- make the undefine flag
+function nf_undefine(self, macro)
+ return "--undef:" .. macro
+end
+
+-- make the optimize flag
+function nf_optimize(self, level)
+ local maps =
+ {
+ none = "--opt:none"
+ , fast = "-d:release"
+ , faster = "-d:release"
+ , fastest = "-d:release"
+ , smallest = {"-d:release", "--opt:size"}
+ , aggressive = "-d:danger"
+ }
+ return maps[level]
+end
+
+-- make the symbol flag
+function nf_symbol(self, level)
+ local maps =
+ {
+ debug = "--debugger:native"
+ }
+ return maps[level]
+end
+
+-- make the strip flag
+function nf_strip(self, level, target)
+ if target:is_plat("linux", "macosx", "bsd") then
+ if level == "debug" or level == "all" then
+ return "--passL:-s"
+ end
+ end
+end
+
+-- make the includedir flag
+function nf_includedir(self, dir)
+ return {"--passC:-I" .. path.translate(dir)}
+end
+
+-- make the link flag
+function nf_link(self, lib, target)
+ if target:is_plat("windows") then
+ return "--passL:" .. lib .. ".lib"
+ else
+ return "--passL:-l" .. lib
+ end
+end
+
+-- make the linkdir flag
+function nf_linkdir(self, dir, target)
+ if target:is_plat("windows") then
+ return {"--passL:-libpath:" .. path.translate(dir)}
+ else
+ return {"--passL:-L" .. path.translate(dir)}
+ end
+end
+
+-- make the build arguments list
+function buildargv(self, sourcefiles, targetkind, targetfile, flags)
+ local flags_extra = {}
+ if targetkind == "static" then
+ -- fix multiple definition of `NimMain', it is only workaround solution
+ -- we need to wait for this problem to be resolved
+ --
+ -- @see https://github.com/nim-lang/Nim/issues/15955
+ local uniquekey = hash.uuid(targetfile):split("-", {plain = true})[1]
+ table.insert(flags_extra, "--passC:-DNimMain=NimMain_" .. uniquekey)
+ table.insert(flags_extra, "--passC:-DNimMainInner=NimMainInner_" .. uniquekey)
+ table.insert(flags_extra, "--passC:-DNimMainModule=NimMainModule_" .. uniquekey)
+ table.insert(flags_extra, "--passC:-DPreMain=PreMain_" .. uniquekey)
+ table.insert(flags_extra, "--passC:-DPreMainInner=PreMainInner_" .. uniquekey)
+ end
+ if targetkind ~= "static" and is_plat("windows") then
+ -- fix link flags for windows
+ -- @see https://github.com/nim-lang/Nim/issues/19033
+ local flags_new = {}
+ local flags_link = {}
+ for _, flag in ipairs(flags) do
+ if flag:find("passL:", 1, true) then
+ table.insert(flags_link, flag)
+ else
+ table.insert(flags_new, flag)
+ end
+ end
+ if #flags_link > 0 then
+ table.insert(flags_new, "--passL:-link")
+ table.join2(flags_new, flags_link)
+ end
+ flags = flags_new
+ end
+ return self:program(), table.join("c", flags, flags_extra, "-o:" .. targetfile, sourcefiles)
+end
+
+-- build the target file
+function build(self, sourcefiles, targetkind, targetfile, flags)
+ os.mkdir(path.directory(targetfile))
+ local program, argv = buildargv(self, sourcefiles, targetkind, targetfile, flags)
+ os.runv(program, argv, {envs = self:runenvs()})
+end
+
+
diff --git a/xmake/modules/core/tools/nvcc.lua b/xmake/modules/core/tools/nvcc.lua
index 784b606c5..2aad54096 100644
--- a/xmake/modules/core/tools/nvcc.lua
+++ b/xmake/modules/core/tools/nvcc.lua
@@ -26,7 +26,7 @@ import("core.project.project")
import("core.platform.platform")
import("core.language.language")
import("private.tools.ccache")
-import("private.utils.progress")
+import("utils.progress")
-- init it
function init(self)
@@ -59,7 +59,7 @@ function nf_symbol(self, level, target)
-- debug? generate *.pdb file
local flags = nil
if level == "debug" then
- flags = "-g -lineinfo"
+ flags = {"-g", "-lineinfo"}
if is_plat("windows") then
local host_flags = nil
local symbolfile = nil
@@ -82,11 +82,10 @@ function nf_symbol(self, level, target)
else
host_flags = "-Zi"
end
- flags = flags .. ' -Xcompiler "' .. host_flags .. '"'
+ table.insert(flags, "-Xcompiler")
+ table.insert(flags, host_flags)
end
end
-
- -- none
return flags
end
@@ -178,6 +177,8 @@ function nf_language(self, stdname)
cxx03 = "--std c++03"
, cxx11 = "--std c++11"
, cxx14 = "--std c++14"
+ , cxx17 = "--std c++17"
+ , cxxlatest = {"--std c++17", "--std c++14", "--std c++11", "--std c++03"}
}
local cxxmaps2 = {}
for k, v in pairs(_g.cxxmaps) do
@@ -185,7 +186,18 @@ function nf_language(self, stdname)
end
table.join2(_g.cxxmaps, cxxmaps2)
end
- return _g.cxxmaps[stdname]
+ local maps = _g.cxxmaps
+ local result = maps[stdname]
+ if type(result) == "table" then
+ for _, v in ipairs(result) do
+ if self:has_flags(v, "cxflags") then
+ result = v
+ maps[stdname] = result
+ break
+ end
+ end
+ end
+ return result
end
-- make the define flag
@@ -200,7 +212,7 @@ end
-- make the includedir flag
function nf_includedir(self, dir)
- return {"-I", dir}
+ return {"-I" .. path.translate(dir)}
end
-- make the sysincludedir flag
@@ -220,7 +232,7 @@ end
-- make the linkdir flag
function nf_linkdir(self, dir)
- return {"-L", dir}
+ return {"-L" .. path.translate(dir)}
end
-- make the rpathdir flag
@@ -258,9 +270,9 @@ function linkargv(self, objectfiles, targetkind, targetfile, flags)
end
-- add `-Wl,--out-implib,outputdir/libxxx.a` for xxx.dll on mingw/gcc
- if targetkind == "shared" and config.plat() == "mingw" then
+ if targetkind == "shared" and is_plat("mingw") then
table.insert(flags_extra, "-Xlinker")
- table.insert(flags_extra, "-Wl,--out-implib," .. path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib"))
+ table.insert(flags_extra, "-Wl,--out-implib," .. path.join(path.directory(targetfile), path.basename(targetfile) .. ".dll.a"))
end
-- make link args
diff --git a/xmake/modules/core/tools/rc.lua b/xmake/modules/core/tools/rc.lua
index 208161b67..6796c0fe0 100644
--- a/xmake/modules/core/tools/rc.lua
+++ b/xmake/modules/core/tools/rc.lua
@@ -25,7 +25,7 @@ import("private.tools.vstool")
-- init it
function init(self)
- if winos.version():gt("winxp") then
+ if self:has_flags("-nologo", "mrcflags") then
-- fix vs2008 on xp, e.g. fatal error RC1106: invalid option: -ologo
self:set("mrcflags", "-nologo")
end
diff --git a/xmake/modules/core/tools/rustc.lua b/xmake/modules/core/tools/rustc.lua
index ade2daea4..ab41620cd 100644
--- a/xmake/modules/core/tools/rustc.lua
+++ b/xmake/modules/core/tools/rustc.lua
@@ -25,24 +25,10 @@ import("core.project.project")
-- init it
function init(self)
-
- -- init arflags
- self:set("rcarflags", "--crate-type=lib")
-
- -- init shflags
- self:set("rcshflags", "--crate-type=dylib")
-
- -- init ldflags
- self:set("rcldflags", "--crate-type=bin")
-
- -- init the file formats
- self:set("formats", { static = "lib$(name).rlib" })
end
-- make the optimize flag
function nf_optimize(self, level)
-
- -- the maps
local maps =
{
none = "-C opt-level=0"
@@ -52,21 +38,15 @@ function nf_optimize(self, level)
, smallest = "-C opt-level=s"
, aggressive = "-C opt-level=z"
}
-
- -- make it
return maps[level]
end
-- make the symbol flag
function nf_symbol(self, level)
-
- -- the maps
local maps =
{
debug = "-C debuginfo=2"
}
-
- -- make it
return maps[level]
end
@@ -75,18 +55,66 @@ function nf_linkdir(self, dir)
return {"-L" .. dir}
end
+-- make the link flag
+function nf_link(self, lib)
+ return "-l" .. lib
+end
+
+-- make the syslink flag
+function nf_syslink(self, lib)
+ return nf_link(self, lib)
+end
+
+-- make the frameworkdir flag, crate module dependency directories
+function nf_frameworkdir(self, frameworkdir)
+ return {"-L", "dependency=" .. frameworkdir}
+end
+
+-- make the framework flag, crate module
+function nf_framework(self, framework)
+ local basename = path.basename(framework)
+ local cratename = basename:match("lib(.-)%-.-") or basename:match("lib(.-)")
+ if cratename then
+ return {"--extern", cratename .. "=" .. framework}
+ end
+end
+
+-- make the rpathdir flag
+function nf_rpathdir(self, dir)
+ dir = path.translate(dir)
+ if self:has_flags({"-C", "link-arg=-Wl,-rpath=$ORIGIN"}, "ldflags") then
+ return {"-C", "link-arg=-Wl,-rpath=" .. (dir:gsub("@[%w_]+", function (name)
+ local maps = {["@loader_path"] = "$ORIGIN", ["@executable_path"] = "$ORIGIN"}
+ return maps[name]
+ end))}
+ elseif self:has_flags({"-C", "link-arg=-Xlinker", "-C", "link-arg=-rpath", "-C", "link-arg=-Xlinker", "-C", "link-arg=@loader_path"}, "ldflags") then
+ return {"-C", "link-arg=-Xlinker",
+ "-C", "link-arg=-rpath",
+ "-C", "link-arg=-Xlinker",
+ "-C", "link-arg=" .. (dir:gsub("%$ORIGIN", "@loader_path"))}
+ end
+end
+
-- make the build arguments list
function buildargv(self, sourcefiles, targetkind, targetfile, flags)
- return self:program(), table.join(flags, "-o", targetfile, sourcefiles)
+ -- add rpath for dylib (macho), e.g. -install_name @rpath/file.dylib
+ local flags_extra = {}
+ if targetkind == "shared" and is_plat("macosx", "iphoneos", "watchos") then
+ table.insert(flags_extra, "-C")
+ table.insert(flags_extra, "link-arg=-Xlinker")
+ table.insert(flags_extra, "-C")
+ table.insert(flags_extra, "link-arg=-install_name")
+ table.insert(flags_extra, "-C")
+ table.insert(flags_extra, "link-arg=-Xlinker")
+ table.insert(flags_extra, "-C")
+ table.insert(flags_extra, "link-arg=@rpath/" .. path.filename(targetfile))
+ end
+ return self:program(), table.join(flags, flags_extra, "-o", targetfile, sourcefiles)
end
-- build the target file
function build(self, sourcefiles, targetkind, targetfile, flags)
-
- -- ensure the target directory
os.mkdir(path.directory(targetfile))
-
- -- build it
os.runv(buildargv(self, sourcefiles, targetkind, targetfile, flags))
end
@@ -97,11 +125,7 @@ end
-- compile the source file
function compile(self, sourcefiles, objectfile, dependinfo, flags)
-
- -- ensure the object directory
os.mkdir(path.directory(objectfile))
-
- -- compile it
os.runv(compargv(self, sourcefiles, objectfile, flags))
end
diff --git a/xmake/modules/core/tools/sdcc.lua b/xmake/modules/core/tools/sdcc.lua
index 00e081384..4605f12f8 100644
--- a/xmake/modules/core/tools/sdcc.lua
+++ b/xmake/modules/core/tools/sdcc.lua
@@ -21,7 +21,7 @@
-- imports
import("core.base.option")
import("core.base.global")
-import("private.utils.progress")
+import("utils.progress")
-- init it
function init(self)
@@ -68,23 +68,17 @@ end
-- make the warning flag
function nf_warning(self, level)
-
- -- the maps
local maps =
{
none = "--less-pedantic"
, less = "--less-pedantic"
, error = "-Werror"
}
-
- -- make it
return maps[level]
end
-- make the optimize flag
function nf_optimize(self, level)
-
- -- the maps
local maps =
{
none = ""
@@ -94,19 +88,14 @@ function nf_optimize(self, level)
, smallest = "--opt-code-size"
, aggressive = "--opt-code-speed"
}
-
- -- make it
return maps[level]
end
-- make the language flag
function nf_language(self, stdname)
-
- -- the stdc maps
if _g.cmaps == nil then
_g.cmaps =
{
- -- stdc
ansi = "--std-c89"
, c89 = "--std-c89"
, gnu89 = "--std-sdcc89"
@@ -116,9 +105,23 @@ function nf_language(self, stdname)
, gnu11 = "--std-sdcc11"
, c20 = "--std-c2x"
, gnu20 = "--std-sdcc2x"
+ , clatest = {"--std-c2x", "--std-c11", "--std-c99", "--std-c89"}
+ , gnulatest = {"--std-sdcc2x", "--std-sdcc11", "--std-sdcc99", "--std-sdcc89"}
}
end
- return _g.cmaps[stdname]
+ local maps = _g.cmaps
+ local result = maps[stdname]
+ if type(result) == "table" then
+ for _, v in ipairs(result) do
+ if self:has_flags(v, "cxflags") then
+ result = v
+ maps[stdname] = result
+ return result
+ end
+ end
+ else
+ return result
+ end
end
-- make the define flag
@@ -163,11 +166,7 @@ end
-- link the target file
function link(self, objectfiles, targetkind, targetfile, flags)
-
- -- ensure the target directory
os.mkdir(path.directory(targetfile))
-
- -- link it
os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
end
diff --git a/xmake/modules/core/tools/zig.lua b/xmake/modules/core/tools/zig.lua
index 2270e2a3e..f0d6c5d98 100644
--- a/xmake/modules/core/tools/zig.lua
+++ b/xmake/modules/core/tools/zig.lua
@@ -55,7 +55,6 @@ function nf_optimize(self, level)
{
none = "-O Debug"
, fast = "-O ReleaseSafe"
- , aggressive = "-O ReleaseFast"
, fastest = "-O ReleaseFast"
, smallest = "-O ReleaseSmall"
, aggressive = "-O ReleaseFast"
@@ -117,11 +116,7 @@ end
-- link the target file
function link(self, objectfiles, targetkind, targetfile, flags)
-
- -- ensure the target directory
os.mkdir(path.directory(targetfile))
-
- -- link it
os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
end
@@ -132,11 +127,7 @@ end
-- compile the source file
function compile(self, sourcefile, objectfile, dependinfo, flags)
-
- -- ensure the object directory
os.mkdir(path.directory(objectfile))
-
- -- compile it
os.runv(compargv(self, sourcefile, objectfile, flags))
end
diff --git a/xmake/modules/detect/sdks/find_iccenv.lua b/xmake/modules/detect/sdks/find_iccenv.lua
index 0e432a99c..84b40fade 100644
--- a/xmake/modules/detect/sdks/find_iccenv.lua
+++ b/xmake/modules/detect/sdks/find_iccenv.lua
@@ -102,6 +102,11 @@ function _find_intel_on_windows(opt)
-- find iclvars_bat.bat
local paths = {"$(env ICPP_COMPILER20)"}
local iclvars_bat = find_file("bin/iclvars.bat", paths)
+ -- look for setvars.bat which is new in 2021
+ if not iclvars_bat then
+ paths = {"$(env ICPP_COMPILER21)"}
+ iclvars_bat = find_file("../../../setvars.bat", paths)
+ end
if iclvars_bat then
-- load iclvars_bat
@@ -123,6 +128,22 @@ function _find_intel_on_linux(opt)
local sdkdir = path.directory(path.directory(icc))
return {sdkdir = sdkdir, bindir = path.directory(icc), path.join(sdkdir, "include"), libdir = path.join(sdkdir, "lib")}
end
+
+ -- find it from oneapi sdk directory
+ local oneapi_rootdirs = {"~/intel/oneapi/compiler", "/opt/intel/oneapi/compiler"}
+ local arch = os.arch() == "x86_64" and "intel64" or "ia32"
+ paths = {}
+ for _, rootdir in ipairs(oneapi_rootdirs) do
+ table.insert(paths, path.join(rootdir, "*", is_host("macosx") and "mac" or "linux", "bin", arch))
+ end
+ if #paths > 0 then
+ local icc = find_file("icc", paths)
+ if icc then
+ local bindir = path.directory(icc)
+ local sdkdir = path.directory(path.directory(bindir))
+ return {sdkdir = sdkdir, bindir = bindir, libdir = path.join(sdkdir, "compiler", "lib", arch)}
+ end
+ end
end
-- find intel c/c++ environment
diff --git a/xmake/modules/detect/sdks/find_ifortenv.lua b/xmake/modules/detect/sdks/find_ifortenv.lua
index f3aafad06..d851b3f6a 100644
--- a/xmake/modules/detect/sdks/find_ifortenv.lua
+++ b/xmake/modules/detect/sdks/find_ifortenv.lua
@@ -102,6 +102,12 @@ function _find_intel_on_windows(opt)
-- find ifortvars_bat.bat
local paths = {"$(env IFORT_COMPILER20)"}
local ifortvars_bat = find_file("bin/ifortvars.bat", paths)
+ -- look for setvars.bat which is new in 2021
+ if not ifortvars_bat then
+ paths = {"$(env IFORT_COMPILER21)"}
+ ifortvars_bat = find_file("../../../setvars.bat", paths)
+ end
+
if ifortvars_bat then
-- load ifortvars_bat
@@ -116,12 +122,28 @@ end
-- find intel fortran envirnoment on linux
function _find_intel_on_linux(opt)
- -- attempt to find the sdk directory
local paths = {"/opt/intel/bin", "/usr/local/bin", "/usr/bin"}
local ifort = find_file("ifort", paths)
if ifort then
- local sdkdir = path.directory(path.directory(ifort))
- return {sdkdir = sdkdir, bindir = path.directory(ifort), path.join(sdkdir, "include"), libdir = path.join(sdkdir, "lib")}
+ local bindir = path.directory(ifort)
+ local sdkdir = path.directory(bindir)
+ return {sdkdir = sdkdir, bindir = bindir, libdir = path.join(sdkdir, "lib")}
+ end
+
+ -- find it from oneapi sdk directory
+ local oneapi_rootdirs = {"~/intel/oneapi/compiler", "/opt/intel/oneapi/compiler"}
+ local arch = os.arch() == "x86_64" and "intel64" or "ia32"
+ paths = {}
+ for _, rootdir in ipairs(oneapi_rootdirs) do
+ table.insert(paths, path.join(rootdir, "*", is_host("macosx") and "mac" or "linux", "bin", arch))
+ end
+ if #paths > 0 then
+ local ifort = find_file("ifort", paths)
+ if ifort then
+ local bindir = path.directory(ifort)
+ local sdkdir = path.directory(path.directory(bindir))
+ return {sdkdir = sdkdir, bindir = bindir, libdir = path.join(sdkdir, "compiler", "lib", arch)}
+ end
end
end
diff --git a/xmake/modules/detect/sdks/find_mdk.lua b/xmake/modules/detect/sdks/find_mdk.lua
new file mode 100644
index 000000000..a2af360f1
--- /dev/null
+++ b/xmake/modules/detect/sdks/find_mdk.lua
@@ -0,0 +1,123 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_mdk.lua
+--
+
+-- imports
+import("lib.detect.find_path")
+import("core.base.option")
+import("core.base.semver")
+import("core.project.config")
+import("core.cache.detectcache")
+
+-- find MDK directory
+function _find_sdkdir(sdkdir)
+ local paths = {
+ "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Keil\\Products\\MDK;Path)"
+ }
+ if sdkdir then
+ table.insert(paths, 1, sdkdir)
+ end
+ local result = find_path("armcc", paths) or find_path("armclang", paths)
+ if not result then
+ -- find it from some logical drives paths
+ paths = {}
+ for _, logical_drive in ipairs(winos.logical_drives()) do
+ table.insert(paths, path.join(logical_drive, "Keil_v5", "ARM"))
+ end
+ result = find_path("armcc", paths) or find_path("armclang", paths)
+ end
+ return result
+end
+
+-- find MDK toolchains
+function _find_mdk(sdkdir)
+
+ -- find mdk directory
+ sdkdir = _find_sdkdir(sdkdir)
+ if not sdkdir or not os.isdir(sdkdir) then
+ return nil
+ end
+ local result = {sdkdir = sdkdir}
+
+ -- get sdk version
+ local sdkver = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Keil\\Products\\MDK;Version")
+ if sdkver then
+ sdkver = semver.match(sdkver, 1, "V%d+%.%d+")
+ if sdkver then
+ result.sdkver = sdkver:rawstr()
+ end
+ end
+
+ -- armcc sdk directory
+ local sdkdir_armcc = path.join(sdkdir, "armcc")
+ if os.isdir(sdkdir_armcc) and os.isfile(path.join(sdkdir_armcc, "bin", "armcc.exe")) then
+ result.sdkdir_armcc = sdkdir_armcc
+ end
+
+ -- armclang sdk directory
+ local sdkdir_armclang = path.join(sdkdir, "armclang")
+ if os.isdir(sdkdir_armclang) and os.isfile(path.join(sdkdir_armclang, "bin", "armclang.exe")) then
+ result.sdkdir_armclang = sdkdir_armclang
+ end
+ return result
+end
+
+-- find MDK toolchains
+--
+-- @param sdkdir the MDK directory
+-- @param opt the argument options, e.g. {verbose = true, force = false}
+--
+-- @return the MDK toolchains. e.g. {sdkver = ..., sdkdir, sdkdir_armcc, sdkdir_armclang}
+--
+-- @code
+--
+-- local toolchains = find_mdk("~/mdk")
+--
+-- @endcode
+--
+function main(sdkdir, opt)
+
+ -- init arguments
+ opt = opt or {}
+
+ -- attempt to load cache first
+ local key = "detect.sdks.find_mdk"
+ local cacheinfo = detectcache:get(key) or {}
+ if not opt.force and cacheinfo.mdk and cacheinfo.mdk.sdkdir and os.isdir(cacheinfo.mdk.sdkdir) then
+ return cacheinfo.mdk
+ end
+
+ -- find mdk
+ local mdk = _find_mdk(sdkdir or config.get("sdk"))
+ if mdk then
+ if opt.verbose or option.get("verbose") then
+ cprint("checking for MDK directory ... ${color.success}%s", mdk.sdkdir)
+ end
+ else
+ if opt.verbose or option.get("verbose") then
+ cprint("checking for MDK directory ... ${color.nothing}${text.nothing}")
+ end
+ end
+
+ -- save to cache
+ cacheinfo.mdk = mdk or false
+ detectcache:set(key, cacheinfo)
+ detectcache:save()
+ return mdk
+end
diff --git a/xmake/modules/detect/sdks/find_mingw.lua b/xmake/modules/detect/sdks/find_mingw.lua
index 7be315a9c..e5276834b 100644
--- a/xmake/modules/detect/sdks/find_mingw.lua
+++ b/xmake/modules/detect/sdks/find_mingw.lua
@@ -94,6 +94,9 @@ function _find_mingw(sdkdir, bindir, cross)
-- find cross toolchain
local toolchain = find_cross_toolchain(sdkdir or bindir, {bindir = bindir, cross = cross})
+ if not toolchain then -- fallback, e.g. gcc.exe without cross
+ toolchain = find_cross_toolchain(sdkdir or bindir, {bindir = bindir})
+ end
if toolchain then
return {sdkdir = toolchain.sdkdir, bindir = toolchain.bindir, cross = toolchain.cross}
end
diff --git a/xmake/modules/detect/sdks/find_ndk.lua b/xmake/modules/detect/sdks/find_ndk.lua
index bc07f6081..ac412bce0 100644
--- a/xmake/modules/detect/sdks/find_ndk.lua
+++ b/xmake/modules/detect/sdks/find_ndk.lua
@@ -50,10 +50,16 @@ function _find_ndkdir(sdkdir)
if not sdkdir then
sdkdir = os.getenv("ANDROID_NDK_HOME") or os.getenv("ANDROID_NDK_ROOT")
if not sdkdir and config.get("android_sdk") then
- sdkdir = path.join(config.get("android_sdk"), "ndk-bundle")
+ local ndkbundle = path.join(config.get("android_sdk"), "ndk-bundle")
+ if os.isdir(ndkbundle) then
+ sdkdir = ndkbundle
+ end
end
if not sdkdir and is_host("macosx") then
- sdkdir = "~/Library/Android/sdk/ndk-bundle"
+ sdkdir = find_directory("NDK", "/Applications/AndroidNDK*.app/Contents")
+ if not sdkdir then
+ sdkdir = "~/Library/Android/sdk/ndk-bundle"
+ end
end
end
@@ -188,8 +194,12 @@ function _find_ndk(sdkdir, arch, ndk_sdkver, ndk_toolchains_ver)
local gcc_toolchain_subdir = gcc_toolchain_subdirs[arch] or "arm-linux-androideabi-*"
-- find the binary directory
- local bindir = find_directory("bin", path.join(sdkdir, "toolchains", "llvm", "prebuilt", "*")) -- larger than ndk r16
- if not bindir then
+ local llvm_toolchain
+ local prebuilt = (is_host("macosx") and "darwin" or os.host()) .. "-x86_64"
+ local bindir = find_directory("bin", path.join(sdkdir, "toolchains", "llvm", "prebuilt", prebuilt)) -- larger than ndk r16
+ if bindir then
+ llvm_toolchain = path.directory(bindir)
+ else
bindir = find_directory("bin", path.join(sdkdir, "toolchains", gcc_toolchain_subdir, "prebuilt", "*"))
end
if not bindir then
@@ -231,6 +241,7 @@ function _find_ndk(sdkdir, arch, ndk_sdkver, ndk_toolchains_ver)
bindir = bindir,
cross = cross,
sdkver = sdkver,
+ llvm_toolchain = llvm_toolchain, -- >= ndk r22
gcc_toolchain = gcc_toolchain,
toolchains_ver = toolchains_ver,
sysroot = sysroot}
@@ -280,7 +291,6 @@ function main(sdkdir, opt)
if opt.verbose or option.get("verbose") then
cprint("checking for NDK directory ... ${color.success}%s", ndk.sdkdir)
cprint("checking for SDK version of NDK ... ${color.success}%s", ndk.sdkver)
- cprint("checking for toolchains version of NDK ... ${color.success}%s", ndk.toolchains_ver)
end
else
diff --git a/xmake/modules/detect/sdks/find_qt.lua b/xmake/modules/detect/sdks/find_qt.lua
index 9dbc7b386..202b52d88 100644
--- a/xmake/modules/detect/sdks/find_qt.lua
+++ b/xmake/modules/detect/sdks/find_qt.lua
@@ -35,7 +35,10 @@ function _find_sdkdir(sdkdir, sdkver)
table.insert(subdirs, path.join(sdkver or "*", is_arch("x86_64") and "gcc_64" or "gcc_32", "bin"))
table.insert(subdirs, path.join(sdkver or "*", is_arch("x86_64") and "clang_64" or "clang_32", "bin"))
elseif is_plat("macosx") then
+ table.insert(subdirs, path.join(sdkver or "*", "macos", "bin")) -- for Qt 6.2
table.insert(subdirs, path.join(sdkver or "*", is_arch("x86_64") and "clang_64" or "clang_32", "bin"))
+ elseif is_plat("iphoneos") then
+ table.insert(subdirs, path.join(sdkver or "*", "ios", "bin"))
elseif is_plat("windows") then
local vs = config.get("vs")
if vs then
@@ -120,11 +123,7 @@ end
-- find qmake
function _find_qmake(sdkdir, sdkver)
-
- -- find qt directory
sdkdir = _find_sdkdir(sdkdir, sdkver)
-
- -- get the bin directory
local qmake = find_tool("qmake", {paths = sdkdir and path.join(sdkdir, "bin")})
if qmake then
return qmake.program
@@ -174,8 +173,27 @@ function _find_qt(sdkdir, sdkver)
local libdir = qtenvs.QT_INSTALL_LIBS
local pluginsdir = qtenvs.QT_INSTALL_PLUGINS
local includedir = qtenvs.QT_INSTALL_HEADERS
- local mkspecsdir = path.join(qtenvs.QT_INSTALL_ARCHDATA, "mkspecs")
- return {sdkdir = sdkdir, bindir = bindir, libexecdir = libexecdir, libdir = libdir, includedir = includedir, qmldir = qmldir, pluginsdir = pluginsdir, mkspecsdir = mkspecsdir, sdkver = sdkver}
+ local mkspecsdir = qtenvs.QMAKE_MKSPECS or path.join(qtenvs.QT_INSTALL_ARCHDATA, "mkspecs")
+ -- for 6.2
+ local bindir_host
+ if libexecdir and is_plat("android", "iphoneos") then
+ local rootdir = path.directory(path.directory(bindir))
+ if is_host("macosx") then
+ bindir_host = path.join(rootdir, "macos", "bin")
+ else
+ -- TODO
+ end
+ end
+ local libexecdir_host
+ if libexecdir and is_plat("android", "iphoneos") then
+ local rootdir = path.directory(path.directory(libexecdir))
+ if is_host("macosx") then
+ libexecdir_host = path.join(rootdir, "macos", "libexec")
+ else
+ -- TODO
+ end
+ end
+ return {sdkdir = sdkdir, bindir = bindir, bindir_host = bindir_host, libexecdir = libexecdir, libexecdir_host = libexecdir_host, libdir = libdir, includedir = includedir, qmldir = qmldir, pluginsdir = pluginsdir, mkspecsdir = mkspecsdir, sdkver = sdkver}
end
-- find qt sdk toolchains
diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua
index 2934d23c8..0b3fb1361 100644
--- a/xmake/modules/detect/sdks/find_vstudio.lua
+++ b/xmake/modules/detect/sdks/find_vstudio.lua
@@ -19,6 +19,7 @@
--
-- imports
+import("core.project.config")
import("lib.detect.find_file")
import("lib.detect.find_tool")
@@ -34,9 +35,66 @@ local vcvars = {"path",
"WindowsLibPath",
"WindowsSDKVersion",
"WindowsSdkBinPath",
+ "WindowsSdkVerBinPath",
+ "ExtensionSdkDir",
"UniversalCRTSdkDir",
"UCRTVersion",
- "VCToolsVersion"}
+ "VCToolsVersion",
+ "VCIDEInstallDir",
+ "VCToolsInstallDir",
+ "VCToolsRedistDir",
+ "VisualStudioVersion",
+ "VSCMD_VER",
+ "VSCMD_ARG_app_plat",
+ "VSCMD_ARG_HOST_ARCH",
+ "VSCMD_ARG_TGT_ARCH"}
+
+-- init vsvers
+local vsvers =
+{
+ ["17.0"] = "2022"
+, ["16.0"] = "2019"
+, ["15.0"] = "2017"
+, ["14.0"] = "2015"
+, ["12.0"] = "2013"
+, ["11.0"] = "2012"
+, ["10.0"] = "2010"
+, ["9.0"] = "2008"
+, ["8.0"] = "2005"
+, ["7.1"] = "2003"
+, ["7.0"] = "7.0"
+, ["6.0"] = "6.0"
+, ["5.0"] = "5.0"
+, ["4.2"] = "4.2"
+}
+
+-- init vsenvs
+local vsenvs =
+{
+ ["17.0"] = "VS170COMNTOOLS"
+, ["16.0"] = "VS160COMNTOOLS"
+, ["15.0"] = "VS150COMNTOOLS"
+, ["14.0"] = "VS140COMNTOOLS"
+, ["12.0"] = "VS120COMNTOOLS"
+, ["11.0"] = "VS110COMNTOOLS"
+, ["10.0"] = "VS100COMNTOOLS"
+, ["9.0"] = "VS90COMNTOOLS"
+, ["8.0"] = "VS80COMNTOOLS"
+, ["7.1"] = "VS71COMNTOOLS"
+, ["7.0"] = "VS70COMNTOOLS"
+, ["6.0"] = "VS60COMNTOOLS"
+, ["5.0"] = "VS50COMNTOOLS"
+, ["4.2"] = "VS42COMNTOOLS"
+}
+
+-- get all known Visual Studio environment variables
+function get_vcvars()
+ local realvcvars = vcvars
+ for _, v in pairs(vsenvs) do
+ table.insert(realvcvars, v)
+ end
+ return realvcvars
+end
-- load vcvarsall environment variables
function _load_vcvarsall(vcvarsall, vsver, arch, opt)
@@ -59,7 +117,7 @@ function _load_vcvarsall(vcvarsall, vsver, arch, opt)
else
file:print("call \"%s\" %s %s > nul", vcvarsall, arch, opt.sdkver and opt.sdkver or "")
end
- for idx, var in ipairs(vcvars) do
+ for idx, var in ipairs(get_vcvars()) do
file:print("echo " .. var .. " = %%" .. var .. "%%")
end
file:close()
@@ -148,41 +206,6 @@ function main(opt)
return
end
- -- init vsvers
- local vsvers =
- {
- ["17.0"] = "2022"
- , ["16.0"] = "2019"
- , ["15.0"] = "2017"
- , ["14.0"] = "2015"
- , ["12.0"] = "2013"
- , ["11.0"] = "2012"
- , ["10.0"] = "2010"
- , ["9.0"] = "2008"
- , ["8.0"] = "2005"
- , ["7.1"] = "2003"
- , ["7.0"] = "7.0"
- , ["6.0"] = "6.0"
- , ["5.0"] = "5.0"
- , ["4.2"] = "4.2"
- }
-
- -- init vsenvs
- local vsenvs =
- {
- ["14.0"] = "VS140COMNTOOLS"
- , ["12.0"] = "VS120COMNTOOLS"
- , ["11.0"] = "VS110COMNTOOLS"
- , ["10.0"] = "VS100COMNTOOLS"
- , ["9.0"] = "VS90COMNTOOLS"
- , ["8.0"] = "VS80COMNTOOLS"
- , ["7.1"] = "VS71COMNTOOLS"
- , ["7.0"] = "VS70COMNTOOLS"
- , ["6.0"] = "VS60COMNTOOLS"
- , ["5.0"] = "VS50COMNTOOLS"
- , ["4.2"] = "VS42COMNTOOLS"
- }
-
-- init options
opt = opt or {}
@@ -255,7 +278,8 @@ function main(opt)
local vswhere_VCAuxiliaryBuildDir = nil
if (tonumber(version) >= 15) and vswhere then
local vswhere_vrange = format("%s,%s)", version, (version + 1))
- local result = os.iorunv(vswhere.program, {"-prerelease", "-property", "installationpath", "-version", vswhere_vrange})
+ -- build tools: https://github.com/microsoft/vswhere/issues/22 @@ https://aka.ms/vs/workloads
+ local result = os.iorunv(vswhere.program, {"-products", "*", "-prerelease", "-property", "installationpath", "-version", vswhere_vrange})
if result then
vswhere_VCAuxiliaryBuildDir = path.join(result:trim(), "VC", "Auxiliary", "Build")
end
@@ -282,7 +306,18 @@ function main(opt)
if not vcvarsall then
-- find vs from some logical drives paths
paths = {}
- for _, logical_drive in ipairs(winos.logical_drives()) do
+ local logical_drives = winos.logical_drives()
+ -- we attempt to find vs from wdk directory
+ -- wdk: E:\Program Files\Windows Kits\10
+ -- vcvarsall: E:\Program Files\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build
+ local wdk = config.get("wdk")
+ if wdk and os.isdir(wdk) then
+ local p = wdk:find("Program Files")
+ if p then
+ table.insert(logical_drives, wdk:sub(1, p - 1))
+ end
+ end
+ for _, logical_drive in ipairs(logical_drives) do
if os.isdir(path.join(logical_drive, "Program Files (x86)")) then
table.insert(paths, path.join(logical_drive, "Program Files (x86)", "Microsoft Visual Studio", vsvers[version], "*", "VC", "Auxiliary", "Build"))
table.insert(paths, path.join(logical_drive, "Program Files (x86)", "Microsoft Visual Studio " .. version, "VC"))
diff --git a/xmake/modules/detect/tools/circle/has_flags.lua b/xmake/modules/detect/tools/circle/has_flags.lua
new file mode 100644
index 000000000..6464e10b6
--- /dev/null
+++ b/xmake/modules/detect/tools/circle/has_flags.lua
@@ -0,0 +1,23 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file has_flags.lua
+--
+
+-- imports
+inherit("detect.tools.gcc.has_flags")
+
diff --git a/xmake/modules/detect/tools/cl/cfeatures.lua b/xmake/modules/detect/tools/cl/cfeatures.lua
index 88c65559f..9b043f7e1 100644
--- a/xmake/modules/detect/tools/cl/cfeatures.lua
+++ b/xmake/modules/detect/tools/cl/cfeatures.lua
@@ -31,6 +31,11 @@ function main()
local msvc_minver = "_MSC_VER >= 1200"
local msvc_2005 = "_MSC_VER >= 1400"
local msvc_2010 = "_MSC_VER >= 1600"
+ local msvc_2019 = "_MSC_VER >= 1920"
+
+ -- set language standard supports
+ _set("c_std_89", msvc_2005)
+ _set("c_std_99", msvc_2019)
-- set features
_set("c_static_assert", msvc_2010)
diff --git a/xmake/modules/detect/tools/cl/cxxfeatures.lua b/xmake/modules/detect/tools/cl/cxxfeatures.lua
index 661af6640..c8b683e6f 100644
--- a/xmake/modules/detect/tools/cl/cxxfeatures.lua
+++ b/xmake/modules/detect/tools/cl/cxxfeatures.lua
@@ -32,6 +32,7 @@ end
-- http://www.visualstudio.com/en-us/news/vs2015-preview-vs.aspx
-- http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx
-- http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx
+-- https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-160
--
-- porting from Modules/Compiler/MSVC-CXX-FeatureTests.cmake
--
@@ -49,6 +50,15 @@ function main()
local msvc_2013 = "_MSC_VER >= 1800"
local msvc_2015 = "_MSC_VER >= 1900"
local msvc_2017 = "_MSC_VER >= 1910"
+ local msvc_2019 = "_MSC_VER >= 1920"
+ local msvc_2022 = "_MSC_VER >= 1930"
+
+ -- set language standard supports
+ _set("cxx_std_98", msvc_2005)
+ _set("cxx_std_11", msvc_2015)
+ _set("cxx_std_14", msvc_2017)
+ _set("cxx_std_17", msvc_2019)
+ _set("cxx_std_20", msvc_2022)
-- VS version 15 (not 2015) introduces support for aggregate initializers.
_set("cxx_aggregate_default_initializers", "_MSC_FULL_VER >= 190024406")
diff --git a/xmake/modules/detect/tools/cl/has_flags.lua b/xmake/modules/detect/tools/cl/has_flags.lua
index a1cb9ace7..1c7f65325 100644
--- a/xmake/modules/detect/tools/cl/has_flags.lua
+++ b/xmake/modules/detect/tools/cl/has_flags.lua
@@ -20,6 +20,7 @@
-- imports
import("core.cache.detectcache")
+import("core.language.language")
-- attempt to check it from the argument list
function _check_from_arglist(flags, opt)
@@ -55,12 +56,17 @@ function _check_from_arglist(flags, opt)
return allflags[flags[1]:gsub("/", "-")]
end
+-- get extension
+function _get_extension(opt)
+ return opt.flagkind == "cxxflags" and ".cpp" or (table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c")
+end
+
-- try running to check flags
function _check_try_running(flags, opt)
-- make an stub source file
local tmpdir = path.join(os.tmpdir(), "detect")
- local sourcefile = path.join(tmpdir, "cl_has_flags.c")
+ local sourcefile = path.join(tmpdir, "cl_has_flags" .. _get_extension(opt))
if not os.isfile(sourcefile) then
io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
end
diff --git a/xmake/modules/detect/tools/clang/cfeatures.lua b/xmake/modules/detect/tools/clang/cfeatures.lua
index 8cdfadfd0..e9a1687a6 100644
--- a/xmake/modules/detect/tools/clang/cfeatures.lua
+++ b/xmake/modules/detect/tools/clang/cfeatures.lua
@@ -33,11 +33,19 @@ function main()
_g.features = cfeatures()
-- init conditions
+ -- clang -std=c11 -dM -E - < /dev/null | grep __STDC_VERSION__
local clang_minver = "((__clang_major__ * 100) + __clang_minor__) >= 304"
+ local c17 = clang_minver .. " && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L"
local c11 = clang_minver .. " && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L"
local c99 = clang_minver .. " && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L"
local c90 = clang_minver
+ -- set language standard supports
+ _set("c_std_89", c90)
+ _set("c_std_99", c99)
+ _set("c_std_11", c11)
+ _set("c_std_17", c17)
+
-- set features
_set("c_static_assert", c11)
_set("c_restrict", c99)
diff --git a/xmake/modules/detect/tools/clang/cxxfeatures.lua b/xmake/modules/detect/tools/clang/cxxfeatures.lua
index bbf3da8b8..1fd57c8d6 100644
--- a/xmake/modules/detect/tools/clang/cxxfeatures.lua
+++ b/xmake/modules/detect/tools/clang/cxxfeatures.lua
@@ -28,6 +28,8 @@ end
-- get features
--
+-- @see http://clang.llvm.org/cxx_status.html
+--
-- porting from Modules/Compiler/Clang-CXX-FeatureTests.cmake
--
function main()
@@ -36,12 +38,22 @@ function main()
_g.features = cxxfeatures()
-- init conditions
+ -- clang -x c++ -std=c++20 -dM -E - < /dev/null | grep __cplusplus
local clang_minver = "((__clang_major__ * 100) + __clang_minor__) >= 301"
+ local clang80_cxx20 = "((__clang_major__ * 100) + __clang_minor__) >= 800 && __cplusplus >= 202002L"
+ local clang50_cxx17 = "((__clang_major__ * 100) + __clang_minor__) >= 500 && __cplusplus >= 201703L"
local clang34_cxx14 = "((__clang_major__ * 100) + __clang_minor__) >= 304 && __cplusplus > 201103L"
local clang31_cxx11 = clang_minver .. " && __cplusplus >= 201103L"
local clang29_cxx11 = clang_minver .. " && __cplusplus >= 201103L"
local clang_cxx98 = clang_minver .. " && __cplusplus >= 199711L"
+ -- set language standard supports
+ _set("cxx_std_98", clang_cxx98)
+ _set("cxx_std_11", clang29_cxx11)
+ _set("cxx_std_14", clang34_cxx14)
+ _set("cxx_std_17", clang50_cxx17)
+ _set("cxx_std_20", clang80_cxx20)
+
-- set features for __has_feature()
local features_of_has_feature =
{
diff --git a/xmake/modules/detect/tools/clang_cl/has_flags.lua b/xmake/modules/detect/tools/clang_cl/has_flags.lua
index 27728697f..4917fb665 100644
--- a/xmake/modules/detect/tools/clang_cl/has_flags.lua
+++ b/xmake/modules/detect/tools/clang_cl/has_flags.lua
@@ -61,7 +61,7 @@ function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- try running to check flags
diff --git a/xmake/modules/detect/tools/dmd/has_flags.lua b/xmake/modules/detect/tools/dmd/has_flags.lua
index 459db9228..235e99d4c 100644
--- a/xmake/modules/detect/tools/dmd/has_flags.lua
+++ b/xmake/modules/detect/tools/dmd/has_flags.lua
@@ -40,7 +40,7 @@ function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- attempt to check it from the argument list
diff --git a/xmake/modules/detect/tools/find_7z.lua b/xmake/modules/detect/tools/find_7z.lua
index b441c2200..ce1a04f4a 100644
--- a/xmake/modules/detect/tools/find_7z.lua
+++ b/xmake/modules/detect/tools/find_7z.lua
@@ -55,6 +55,11 @@ function main(opt)
program = find_program("7za", opt)
end
+ -- find it from msys/mingw, it is only a shell script
+ if not program and is_subhost("msys") then
+ program = find_program("sh 7z", opt)
+ end
+
-- find program version
local version = nil
if program and opt and opt.version then
diff --git a/xmake/modules/detect/tools/find_armar.lua b/xmake/modules/detect/tools/find_armar.lua
new file mode 100644
index 000000000..725d6a988
--- /dev/null
+++ b/xmake/modules/detect/tools/find_armar.lua
@@ -0,0 +1,65 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_armar.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("detect.sdks.find_mdk")
+
+-- find armar
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local armar = find_armar()
+-- local armar, version = find_armar({program = "armar", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = "-h"
+
+ -- find program
+ local program = find_program(opt.program or "armar.exe", opt)
+ if not program then
+ local mdk = find_mdk()
+ if mdk then
+ if mdk.sdkdir_armcc then
+ program = find_program(path.join(mdk.sdkdir_armcc, "bin", "armar.exe"), opt)
+ end
+ if not program and mdk.sdkdir_armclang then
+ program = find_program(path.join(mdk.sdkdir_armclang, "bin", "armar.exe"), opt)
+ end
+ end
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_armasm.lua b/xmake/modules/detect/tools/find_armasm.lua
new file mode 100644
index 000000000..280333195
--- /dev/null
+++ b/xmake/modules/detect/tools/find_armasm.lua
@@ -0,0 +1,65 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_armasm.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("detect.sdks.find_mdk")
+
+-- find armasm
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local armasm = find_armasm()
+-- local armasm, version = find_armasm({program = "armasm", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = "-h"
+
+ -- find program
+ local program = find_program(opt.program or "armasm.exe", opt)
+ if not program then
+ local mdk = find_mdk()
+ if mdk then
+ if mdk.sdkdir_armcc then
+ program = find_program(path.join(mdk.sdkdir_armcc, "bin", "armasm.exe"), opt)
+ end
+ if not program and mdk.sdkdir_armclang then
+ program = find_program(path.join(mdk.sdkdir_armclang, "bin", "armasm.exe"), opt)
+ end
+ end
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_armcc.lua b/xmake/modules/detect/tools/find_armcc.lua
new file mode 100644
index 000000000..584e9b3a9
--- /dev/null
+++ b/xmake/modules/detect/tools/find_armcc.lua
@@ -0,0 +1,60 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_armcc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("detect.sdks.find_mdk")
+
+-- find armcc
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local armcc = find_armcc()
+-- local armcc, version = find_armcc({program = "armcc", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = "-h"
+
+ -- find program
+ local program = find_program(opt.program or "armcc.exe", opt)
+ if not program then
+ local mdk = find_mdk()
+ if mdk and mdk.sdkdir_armcc then
+ program = find_program(path.join(mdk.sdkdir_armcc, "bin", "armcc.exe"), opt)
+ end
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_armclang.lua b/xmake/modules/detect/tools/find_armclang.lua
new file mode 100644
index 000000000..ed6b0bbfe
--- /dev/null
+++ b/xmake/modules/detect/tools/find_armclang.lua
@@ -0,0 +1,59 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_armclang.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("detect.sdks.find_mdk")
+
+-- find armclang
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local armclang = find_armclang()
+-- local armclang, version = find_armclang({program = "armclang", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "armclang.exe", opt)
+ if not program then
+ local mdk = find_mdk()
+ if mdk and mdk.sdkdir_armclang then
+ program = find_program(path.join(mdk.sdkdir_armclang, "bin", "armclang.exe"), opt)
+ end
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_armlink.lua b/xmake/modules/detect/tools/find_armlink.lua
new file mode 100644
index 000000000..3ab383c86
--- /dev/null
+++ b/xmake/modules/detect/tools/find_armlink.lua
@@ -0,0 +1,65 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_armlink.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("detect.sdks.find_mdk")
+
+-- find armlink
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local armlink = find_armlink()
+-- local armlink, version = find_armlink({program = "armlink", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = "-h"
+
+ -- find program
+ local program = find_program(opt.program or "armlink.exe", opt)
+ if not program then
+ local mdk = find_mdk()
+ if mdk then
+ if mdk.sdkdir_armcc then
+ program = find_program(path.join(mdk.sdkdir_armcc, "bin", "armlink.exe"), opt)
+ end
+ if not program and mdk.sdkdir_armclang then
+ program = find_program(path.join(mdk.sdkdir_armclang, "bin", "armlink.exe"), opt)
+ end
+ end
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_cargo.lua b/xmake/modules/detect/tools/find_cargo.lua
new file mode 100644
index 000000000..a67b29821
--- /dev/null
+++ b/xmake/modules/detect/tools/find_cargo.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_cargo.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find nim
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local nim = find_cargo()
+-- local nim, version = find_cargo({program = "cargo", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "cargo", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_circle.lua b/xmake/modules/detect/tools/find_circle.lua
new file mode 100644
index 000000000..ba2f805c2
--- /dev/null
+++ b/xmake/modules/detect/tools/find_circle.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_circle.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find circle
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local circle = find_circle()
+-- local circle, version = find_circle({program = "circle", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "circle", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_cxxbridge.lua b/xmake/modules/detect/tools/find_cxxbridge.lua
new file mode 100644
index 000000000..400573fa7
--- /dev/null
+++ b/xmake/modules/detect/tools/find_cxxbridge.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_cxxbridge.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find nim
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local nim = find_cxxbridge()
+-- local nim, version = find_cxxbridge({program = "cxxbridge", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "cxxbridge", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_fpc.lua b/xmake/modules/detect/tools/find_fpc.lua
new file mode 100644
index 000000000..8414acba8
--- /dev/null
+++ b/xmake/modules/detect/tools/find_fpc.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_fpc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find fpc
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local fpc = find_fpc()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = opt.check or "-h"
+
+ -- find program
+ local program = find_program(opt.program or "fpc", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_glslangValidator.lua b/xmake/modules/detect/tools/find_glslangValidator.lua
new file mode 100644
index 000000000..93bc94670
--- /dev/null
+++ b/xmake/modules/detect/tools/find_glslangValidator.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_glslangValidator.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find glslangValidator
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local glslangValidator = find_glslangValidator()
+-- local glslangValidator, version = find_glslangValidator({program = "glslangValidator", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "glslangValidator", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_glslc.lua b/xmake/modules/detect/tools/find_glslc.lua
new file mode 100644
index 000000000..ada89e672
--- /dev/null
+++ b/xmake/modules/detect/tools/find_glslc.lua
@@ -0,0 +1,61 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_glslc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("core.tool.toolchain")
+
+-- find glslc
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local glslc = find_glslc()
+-- local glslc, version = find_glslc({program = "glslc", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "glslc", opt)
+ if not program and is_plat("android") then
+ local ndk = toolchain.load("ndk"):config("ndk")
+ if ndk then
+ local prebuilt = (is_host("macosx") and "darwin" or os.host()) .. "-x86_64"
+ opt.paths = path.join(ndk, "shader-tools", prebuilt)
+ program = find_program(opt.program or "glslc", opt)
+ end
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_ifort.lua b/xmake/modules/detect/tools/find_ifort.lua
index ecdb94dfd..31f158996 100644
--- a/xmake/modules/detect/tools/find_ifort.lua
+++ b/xmake/modules/detect/tools/find_ifort.lua
@@ -36,7 +36,6 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
-
opt = opt or {}
if is_host("windows") then
-- find program
diff --git a/xmake/modules/detect/tools/find_llvm_as.lua b/xmake/modules/detect/tools/find_llvm_as.lua
new file mode 100644
index 000000000..213f63abf
--- /dev/null
+++ b/xmake/modules/detect/tools/find_llvm_as.lua
@@ -0,0 +1,57 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author xq114
+-- @file find_llvm_as.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find llvm-ar
+--
+-- @param opt the argument options, e.g. {version = true, program = "c:\xxx\llvm-as.exe"}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local llvm_as = find_llvm_as()
+-- local llvm_as, version = find_llvm_as({version = true})
+-- local llvm_as, version = find_llvm_as({version = true, program = "c:\xxx\llvm-as.exe"})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = opt.check or "-version"
+ opt.command = opt.command or "-version"
+
+ -- find program
+ local program = find_program(opt.program or "llvm-as", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_make.lua b/xmake/modules/detect/tools/find_make.lua
new file mode 100644
index 000000000..eb2957d63
--- /dev/null
+++ b/xmake/modules/detect/tools/find_make.lua
@@ -0,0 +1,53 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_make.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find make
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local make = find_make()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- find program
+ opt = opt or {}
+ local program = find_program(opt.program or (is_host("bsd") and "gmake" or "make"), opt)
+ if not program and not opt.program and is_subhost("msys", "cygwin") then
+ program = find_program("mingw32-make.exe", opt)
+ end
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
+
diff --git a/xmake/modules/detect/tools/find_metal.lua b/xmake/modules/detect/tools/find_metal.lua
new file mode 100644
index 000000000..71a01728b
--- /dev/null
+++ b/xmake/modules/detect/tools/find_metal.lua
@@ -0,0 +1,50 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_metal.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find metal
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local metal = find_metal()
+-- local metal, version = find_metal({program = "xcrun -sdk macosx metal", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- find program
+ opt = opt or {}
+ local program = find_program(opt.program or "xcrun -sdk macosx metal", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_metallib.lua b/xmake/modules/detect/tools/find_metallib.lua
new file mode 100644
index 000000000..6989729f9
--- /dev/null
+++ b/xmake/modules/detect/tools/find_metallib.lua
@@ -0,0 +1,50 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_metallib.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find metallib
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local metallib = find_metallib()
+-- local metallib, version = find_metallib({program = "xcrun -sdk macosx metallib", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- find program
+ opt = opt or {}
+ local program = find_program(opt.program or "xcrun -sdk macosx metallib", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_nim.lua b/xmake/modules/detect/tools/find_nim.lua
new file mode 100644
index 000000000..ae524ddbc
--- /dev/null
+++ b/xmake/modules/detect/tools/find_nim.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_nim.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find nim
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local nim = find_nim()
+-- local nim, version = find_nim({program = "nim", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "nim", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_nimble.lua b/xmake/modules/detect/tools/find_nimble.lua
new file mode 100644
index 000000000..7d4364b64
--- /dev/null
+++ b/xmake/modules/detect/tools/find_nimble.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_nimble.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find nim
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local nim = find_nimble()
+-- local nim, version = find_nimble({program = "nimble", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "nimble", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_pkg_config.lua b/xmake/modules/detect/tools/find_pkg_config.lua
index 00698d2cc..0dc83454a 100644
--- a/xmake/modules/detect/tools/find_pkg_config.lua
+++ b/xmake/modules/detect/tools/find_pkg_config.lua
@@ -48,7 +48,5 @@ function main(opt)
if program and opt and opt.version then
version = find_programver(program, opt)
end
-
- -- ok?
return program, version
end
diff --git a/xmake/modules/detect/tools/find_pkgconf.lua b/xmake/modules/detect/tools/find_pkgconf.lua
new file mode 100644
index 000000000..563989268
--- /dev/null
+++ b/xmake/modules/detect/tools/find_pkgconf.lua
@@ -0,0 +1,52 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_pkgconf.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find pkgconf
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local pkgconf = find_pkgconf()
+-- local pkgconf, version = find_pkgconf({version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "pkgconf", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_swig.lua b/xmake/modules/detect/tools/find_swig.lua
new file mode 100644
index 000000000..25220030e
--- /dev/null
+++ b/xmake/modules/detect/tools/find_swig.lua
@@ -0,0 +1,53 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_swig.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find swig
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local swig = find_swig()
+-- local swig, version = find_swig({program = "swig", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = opt.check or "-version"
+
+ -- find program
+ local program = find_program(opt.program or "swig", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/fpc/has_flags.lua b/xmake/modules/detect/tools/fpc/has_flags.lua
new file mode 100644
index 000000000..109e1014b
--- /dev/null
+++ b/xmake/modules/detect/tools/fpc/has_flags.lua
@@ -0,0 +1,98 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file has_flags.lua
+--
+
+-- imports
+import("core.cache.detectcache")
+
+-- try running
+function _try_running(...)
+
+ local argv = {...}
+ local errors = nil
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+end
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flags, opt)
+
+ -- only one flag?
+ if #flags > 1 then
+ return
+ end
+
+ -- make cache key
+ local key = "detect.tools.fpc.has_flags"
+
+ -- make allflags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- get all allflags from argument list
+ local allflags = detectcache:get2(key, flagskey)
+ if not allflags then
+
+ -- get argument list
+ allflags = {}
+ local arglist = os.iorunv(opt.program, {"-h"})
+ if arglist then
+ for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
+ allflags[arg] = true
+ end
+ end
+
+ -- save cache
+ detectcache:set2(key, flagskey, allflags)
+ detectcache:save()
+ end
+ return allflags[flags[1]]
+end
+
+-- try running to check flags
+function _check_try_running(flags, opt)
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "fpc_has_flags.pas")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, "program Hello;\nbegin\nend.")
+ end
+
+ -- check it
+ local binaryfile = os.tmpfile()
+ local ok, errors = _try_running(opt.program, table.join(flags, "-o" .. binaryfile, sourcefile))
+ os.tryrm(binaryfile)
+ return ok, errors
+end
+
+-- has_flags(flags)?
+--
+-- @param opt the argument options, e.g. {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flags, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flags, opt) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flags, opt)
+end
+
diff --git a/xmake/modules/detect/tools/gcc/cfeatures.lua b/xmake/modules/detect/tools/gcc/cfeatures.lua
index 664892720..b9ebaa036 100644
--- a/xmake/modules/detect/tools/gcc/cfeatures.lua
+++ b/xmake/modules/detect/tools/gcc/cfeatures.lua
@@ -29,10 +29,17 @@ function main()
-- init conditions
local gcc_minver = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 304"
+ local gcc10_c17 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 1000 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L"
local gcc46_c11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201000L"
local gcc34_c99 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 304 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L"
local gcc_c90 = gcc_minver
+ -- set language standard supports
+ _set("c_std_89", gcc46_c90)
+ _set("c_std_99", gcc34_c99)
+ _set("c_std_11", gcc46_c11)
+ _set("c_std_17", gcc46_c17)
+
-- set features
_set("c_static_assert", gcc46_c11) -- GNU 4.7 correctly sets __STDC_VERSION__ to 201112L, but GNU 4.6 sets it to 201000L
_set("c_restrict", gcc34_c99)
diff --git a/xmake/modules/detect/tools/gcc/cxxfeatures.lua b/xmake/modules/detect/tools/gcc/cxxfeatures.lua
index 4edb33a27..9d628522c 100644
--- a/xmake/modules/detect/tools/gcc/cxxfeatures.lua
+++ b/xmake/modules/detect/tools/gcc/cxxfeatures.lua
@@ -28,13 +28,17 @@ end
--
-- http://gcc.gnu.org/projects/cxx0x.html
-- http://gcc.gnu.org/projects/cxx1y.html
+-- https://gcc.gnu.org/projects/cxx-status.html
--
-- porting from Modules/Compiler/GNU-CXX-FeatureTests.cmake
--
function main()
-- init conditions
+ -- gcc -x c++ -std=c++20 -dM -E - < /dev/null | grep __cplusplus
local gcc_minver = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404"
+ local gcc90_cxx20 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 900 && __cplusplus >= 202002L"
+ local gcc70_cxx17 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 700 && __cplusplus >= 201703L"
local gcc50_cxx14 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L"
local gcc49_cxx14 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L"
local gcc481_cxx11 = "((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40801) && __cplusplus >= 201103L"
@@ -46,6 +50,13 @@ function main()
local gcc44_cxx11 = "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && " .. gcc_cxx0x_defined
local gcc43_cxx11 = gcc_minver .. " && " .. gcc_cxx0x_defined
+ -- set language standard supports
+ _set("cxx_std_98", gcc_minver)
+ _set("cxx_std_11", gcc43_cxx11)
+ _set("cxx_std_14", gcc49_cxx14)
+ _set("cxx_std_17", gcc70_cxx17)
+ _set("cxx_std_20", gcc90_cxx20)
+
-- set features
_set("cxx_variable_templates", gcc50_cxx14)
_set("cxx_relaxed_constexpr", gcc50_cxx14)
@@ -151,6 +162,60 @@ function main()
_set("cxx_variadic_macros", gcc_minver .. " && " .. gcc_cxx0x_defined)
_set("cxx_template_template_parameters", gcc_minver .. " && __cplusplus")
+ -- c++17 language features with predefined macros
+ -- https://en.cppreference.com/w/cpp/feature_test
+ local features_cxx17 = {
+ "__cpp_aggregate_bases",
+ "__cpp_aligned_new",
+ "__cpp_capture_star_this",
+ "__cpp_constexpr",
+ "__cpp_deduction_guides",
+ "__cpp_enumerator_attributes",
+ "__cpp_fold_expressions",
+ "__cpp_guaranteed_copy_elision",
+ "__cpp_hex_float",
+ "__cpp_if_constexpr",
+ "__cpp_inheriting_constructors",
+ "__cpp_inline_variables",
+ "__cpp_namespace_attributes",
+ "__cpp_noexcept_function_type",
+ "__cpp_nontype_template_args",
+ "__cpp_nontype_template_parameter_auto",
+ "__cpp_range_based_for",
+ "__cpp_static_assert",
+ "__cpp_structured_bindings",
+ "__cpp_template_template_args",
+ "__cpp_variadic_using"}
+ for _, feature in ipairs(features_cxx17) do
+ _set((feature:gsub("__cpp", "cxx")), "__cplusplus && defined(" .. feature .. ")")
+ end
+
+ -- c++20 language features with predefined macros
+ -- https://en.cppreference.com/w/cpp/feature_test
+ local features_cxx20 = {
+ "__cpp_aggregate_paren_init",
+ "__cpp_char8_t",
+ "__cpp_concepts",
+ "__cpp_conditional_explicit",
+ "__cpp_consteval",
+ "__cpp_constexpr",
+ "__cpp_constexpr_dynamic_alloc",
+ "__cpp_constexpr_in_decltype",
+ "__cpp_constinit",
+ "__cpp_deduction_guides",
+ "__cpp_designated_initializers",
+ "__cpp_generic_lambdas",
+ "__cpp_impl_coroutine",
+ "__cpp_impl_destroying_delete",
+ "__cpp_impl_three_way_comparison",
+ "__cpp_init_captures",
+ "__cpp_modules",
+ "__cpp_nontype_template_args",
+ "__cpp_using_enum"}
+ for _, feature in ipairs(features_cxx20) do
+ _set((feature:gsub("__cpp", "cxx")), "__cplusplus && defined(" .. feature .. ")")
+ end
+
-- get features
return _g.features
end
diff --git a/xmake/modules/detect/tools/gcc/has_flags.lua b/xmake/modules/detect/tools/gcc/has_flags.lua
index 391ff2bfb..f7cf1d29e 100644
--- a/xmake/modules/detect/tools/gcc/has_flags.lua
+++ b/xmake/modules/detect/tools/gcc/has_flags.lua
@@ -44,47 +44,40 @@ end
-- attempt to check it from the argument list
function _check_from_arglist(flags, opt, islinker)
-
- -- only for compiler
- if islinker or #flags > 1 then
- return
- end
-
- -- make cache key
- local key = "detect.tools.gcc.has_flags"
-
- -- make flags key
+ local key = "detect.tools.gcc." .. (islinker and "has_ldflags" or "has_cflags")
local flagskey = opt.program .. "_" .. (opt.programver or "")
-
- -- get all flags from argument list
local allflags = detectcache:get2(key, flagskey)
if not allflags then
-
- -- get argument list
allflags = {}
- local arglist = os.iorunv(opt.program, {"--help"}, {envs = opt.envs})
+ local arglist = try {function () return os.iorunv(opt.program, {islinker and "-Wl,--help" or "--help"}, {envs = opt.envs}) end}
if arglist then
for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
allflags[arg] = true
end
end
-
- -- save cache
detectcache:set2(key, flagskey, allflags)
detectcache:save()
end
- return allflags[flags[1]]
+ local flag = flags[1]
+ if islinker and flag then
+ if flag:startswith("-Wl,") then
+ flag = flag:match("-Wl,(.-),") or flag:sub(5)
+ end
+ end
+ return allflags[flag]
+end
+
+-- get extension
+function _get_extension(opt)
+ -- @note we need detect extension for ndk/clang++.exe: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
+ return (opt.program:endswith("++") or opt.flagkind == "cxxflags") and ".cpp" or (table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c")
end
-- try running to check flags
function _check_try_running(flags, opt, islinker)
- -- get extension
- -- @note we need detect extension for ndk/clang++.exe: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
- local extension = opt.program:endswith("++") and ".cpp" or (table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c")
-
-- make an stub source file
- local sourcefile = path.join(os.tmpdir(), "detect", "gcc_has_flags" .. extension)
+ local sourcefile = path.join(os.tmpdir(), "detect", "gcc_has_flags" .. _get_extension(opt))
if not os.isfile(sourcefile) then
io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
end
diff --git a/xmake/modules/detect/tools/go/has_flags.lua b/xmake/modules/detect/tools/go/has_flags.lua
index 267d4de8a..e1acf3769 100644
--- a/xmake/modules/detect/tools/go/has_flags.lua
+++ b/xmake/modules/detect/tools/go/has_flags.lua
@@ -35,7 +35,7 @@ function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- attempt to check it from the argument list
diff --git a/xmake/modules/detect/tools/ml/has_flags.lua b/xmake/modules/detect/tools/ml/has_flags.lua
index 53576fa22..0dbda2134 100644
--- a/xmake/modules/detect/tools/ml/has_flags.lua
+++ b/xmake/modules/detect/tools/ml/has_flags.lua
@@ -61,12 +61,21 @@ function _check_try_running(flags, opt)
-- make an stub source file
local sourcefile = path.join(os.tmpdir(), "detect", "ml_has_flags.asm")
if not os.isfile(sourcefile) then
- io.writefile(sourcefile, ".code\nend")
+ io.writefile(sourcefile, [[
+ifndef X64
+.686p
+.model flat, C
+endif
+.code
+end]])
end
-- check it
local errors = nil
return try { function ()
+ if opt.program:find("ml64", 1, true) then
+ table.insert(flags, "-DX64")
+ end
local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. os.nuldev(), sourcefile), {envs = opt.envs})
if errs and #errs:trim() > 0 then
return false, errs
diff --git a/xmake/modules/detect/tools/nim/has_flags.lua b/xmake/modules/detect/tools/nim/has_flags.lua
new file mode 100644
index 000000000..5538257fb
--- /dev/null
+++ b/xmake/modules/detect/tools/nim/has_flags.lua
@@ -0,0 +1,98 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file has_flags.lua
+--
+
+-- imports
+import("core.cache.detectcache")
+
+-- try running
+function _try_running(...)
+
+ local argv = {...}
+ local errors = nil
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+end
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flags, opt)
+
+ -- only one flag?
+ if #flags > 1 then
+ return
+ end
+
+ -- make cache key
+ local key = "detect.tools.nim.has_flags"
+
+ -- make allflags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- get all allflags from argument list
+ local allflags = detectcache:get2(key, flagskey)
+ if not allflags then
+
+ -- get argument list
+ allflags = {}
+ local arglist = os.iorunv(opt.program, {"--help"})
+ if arglist then
+ for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
+ allflags[arg] = true
+ end
+ end
+
+ -- save cache
+ detectcache:set2(key, flagskey, allflags)
+ detectcache:save()
+ end
+ return allflags[flags[1]]
+end
+
+-- try running to check flags
+function _check_try_running(flags, opt)
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "nim_has_flags.nim")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, "echo \"hello\"")
+ end
+
+ -- check it
+ local cachedir = os.tmpfile() .. ".dir"
+ local ok, errors = _try_running(opt.program, table.join("c", "-c", flags, "--nimcache:" .. cachedir, sourcefile))
+ os.tryrm(cachedir)
+ return ok, errors
+end
+
+-- has_flags(flags)?
+--
+-- @param opt the argument options, e.g. {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flags, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flags, opt) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flags, opt)
+end
+
diff --git a/xmake/modules/detect/tools/rc/has_flags.lua b/xmake/modules/detect/tools/rc/has_flags.lua
new file mode 100644
index 000000000..ac023c466
--- /dev/null
+++ b/xmake/modules/detect/tools/rc/has_flags.lua
@@ -0,0 +1,68 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file has_flags.lua
+--
+
+-- imports
+import("core.cache.detectcache")
+import("core.language.language")
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flags, opt)
+
+ -- only one flag?
+ if #flags > 1 then
+ return
+ end
+
+ -- make cache key
+ local key = "detect.tools.rc.has_flags"
+
+ -- make allflags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- get all allflags from argument list
+ local allflags = detectcache:get2(key, flagskey)
+ if not allflags then
+
+ -- get argument list
+ allflags = {}
+ local arglist = os.iorunv(opt.program, {"-?"}, {envs = opt.envs})
+ if arglist then
+ for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do
+ allflags[arg:gsub("/", "-")] = true
+ end
+ end
+
+ -- save cache
+ detectcache:set2(key, flagskey, allflags)
+ detectcache:save()
+ end
+ return allflags[flags[1]:gsub("/", "-")]
+end
+
+-- has_flags(flags)?
+--
+-- @param opt the argument options, e.g. {toolname = "", program = "", programver = ""}
+--
+-- @return true or false
+--
+function main(flags, opt)
+ return _check_from_arglist(flags, opt)
+end
+
diff --git a/xmake/modules/detect/tools/rustc/has_flags.lua b/xmake/modules/detect/tools/rustc/has_flags.lua
index e7c55a180..e1696e454 100644
--- a/xmake/modules/detect/tools/rustc/has_flags.lua
+++ b/xmake/modules/detect/tools/rustc/has_flags.lua
@@ -21,12 +21,22 @@
-- imports
import("core.cache.detectcache")
+-- is linker?
+function _islinker(flags, opt)
+ local flags_str = table.concat(flags, " ")
+ if flags_str:startswith("-C linkarg=") then
+ return true
+ end
+ local toolkind = opt.toolkind or ""
+ return toolkind == "ld" or toolkind == "sh" or toolkind:endswith("ld") or toolkind:endswith("sh")
+end
+
-- try running
function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- attempt to check it from the argument list
@@ -64,7 +74,7 @@ function _check_from_arglist(flags, opt)
end
-- try running to check flags
-function _check_try_running(flags, opt)
+function _check_try_running(flags, opt, islinker)
-- make an stub source file
local sourcefile = path.join(os.tmpdir(), "detect", "rustc_has_flags.rs")
@@ -72,14 +82,15 @@ function _check_try_running(flags, opt)
io.writefile(sourcefile, "fn main() {\n}")
end
- -- check it
+ -- check flags for linker
+ if islinker then
+ return _try_running(opt.program, table.join("--crate-type=bin", flags, "-o", os.tmpfile(), sourcefile), opt)
+ end
+
+ -- check flags for compiler
local objectfile = os.tmpfile() .. ".o"
local ok, errors = _try_running(opt.program, table.join("--emit", "obj", flags, "-o", objectfile, sourcefile))
-
- -- remove files
os.tryrm(objectfile)
-
- -- ok?
return ok, errors
end
@@ -91,12 +102,15 @@ end
--
function main(flags, opt)
+ -- is linker?
+ local islinker = _islinker(flags, opt)
+
-- attempt to check it from the argument list
if _check_from_arglist(flags, opt) then
return true
end
-- try running to check it
- return _check_try_running(flags, opt)
+ return _check_try_running(flags, opt, islinker)
end
diff --git a/xmake/modules/detect/tools/sdcc/has_flags.lua b/xmake/modules/detect/tools/sdcc/has_flags.lua
index 1198b6f44..c7c440a8a 100644
--- a/xmake/modules/detect/tools/sdcc/has_flags.lua
+++ b/xmake/modules/detect/tools/sdcc/has_flags.lua
@@ -41,7 +41,7 @@ function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- attempt to check it from the argument list
diff --git a/xmake/modules/detect/tools/swiftc/has_flags.lua b/xmake/modules/detect/tools/swiftc/has_flags.lua
index 541b897a9..fc4ff6540 100644
--- a/xmake/modules/detect/tools/swiftc/has_flags.lua
+++ b/xmake/modules/detect/tools/swiftc/has_flags.lua
@@ -26,7 +26,7 @@ function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- attempt to check it from the argument list
diff --git a/xmake/modules/detect/tools/zig/has_flags.lua b/xmake/modules/detect/tools/zig/has_flags.lua
index b12f3defb..1dea91cfe 100644
--- a/xmake/modules/detect/tools/zig/has_flags.lua
+++ b/xmake/modules/detect/tools/zig/has_flags.lua
@@ -34,7 +34,7 @@ function _try_running(...)
local argv = {...}
local errors = nil
- return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
+ return try { function () os.runv(table.unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end
-- attempt to check it from the argument list
diff --git a/xmake/modules/devel/git/apply.lua b/xmake/modules/devel/git/apply.lua
index 97923da02..ccfd5bf80 100644
--- a/xmake/modules/devel/git/apply.lua
+++ b/xmake/modules/devel/git/apply.lua
@@ -44,17 +44,6 @@ function main(patchfile, opt)
opt = opt or {}
local argv = {"apply", "--reject", "--ignore-whitespace", patchfile}
- -- enter repository directory
- local oldir = nil
- if opt.repodir then
- oldir = os.cd(opt.repodir)
- end
-
-- apply it
- os.vrunv(git.program, argv)
-
- -- leave repository directory
- if oldir then
- os.cd(oldir)
- end
+ os.vrunv(git.program, argv, {curdir = opt.repodir})
end
diff --git a/xmake/modules/devel/git/checkout.lua b/xmake/modules/devel/git/checkout.lua
index 7a32aa3b1..c78d8f439 100644
--- a/xmake/modules/devel/git/checkout.lua
+++ b/xmake/modules/devel/git/checkout.lua
@@ -47,17 +47,6 @@ function main(commit, opt)
-- init argv
local argv = {"checkout", commit}
- -- enter repository directory
- local oldir = nil
- if opt.repodir then
- oldir = os.cd(opt.repodir)
- end
-
-- checkout it
- os.vrunv(git.program, argv)
-
- -- leave repository directory
- if oldir then
- os.cd(oldir)
- end
+ os.vrunv(git.program, argv, {curdir = opt.repodir})
end
diff --git a/xmake/modules/devel/git/clean.lua b/xmake/modules/devel/git/clean.lua
index ae21c3d88..52fa81a0b 100644
--- a/xmake/modules/devel/git/clean.lua
+++ b/xmake/modules/devel/git/clean.lua
@@ -61,17 +61,6 @@ function main(opt)
table.insert(argv, "-x")
end
- -- enter repository directory
- local oldir = nil
- if opt.repodir then
- oldir = os.cd(opt.repodir)
- end
-
-- clean it
- os.vrunv(git.program, argv)
-
- -- leave repository directory
- if oldir then
- os.cd(oldir)
- end
+ os.vrunv(git.program, argv, {curdir = opt.repodir})
end
diff --git a/xmake/modules/devel/git/lastcommit.lua b/xmake/modules/devel/git/lastcommit.lua
new file mode 100644
index 000000000..1ad6de1f4
--- /dev/null
+++ b/xmake/modules/devel/git/lastcommit.lua
@@ -0,0 +1,66 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file lastcommit.lua
+--
+
+-- imports
+import("core.base.option")
+import("lib.detect.find_tool")
+import("net.proxy")
+
+-- get last commit in git repository
+--
+-- @param opt the options, e.g. {repodir = ..}
+--
+-- @return the last commit
+--
+-- @code
+--
+-- import("devel.git")
+--
+-- local lastcommit = git.lastcommit({repodir = ..})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- find git
+ local git = assert(find_tool("git"), "git not found!")
+
+ -- init arguments
+ local argv = {"rev-parse", "HEAD"}
+
+ -- trace
+ if option.get("verbose") then
+ print("%s %s", git.program, os.args(argv))
+ end
+
+ -- use proxy?
+ local envs
+ local proxy_conf = proxy.config(url)
+ if proxy_conf then
+ envs = {ALL_PROXY = proxy_conf}
+ end
+
+ -- get last commit
+ local lastcommit = os.iorunv(git.program, argv, {envs = envs, curdir = opt.repodir})
+ if lastcommit then
+ lastcommit = lastcommit:trim()
+ end
+ return lastcommit
+end
diff --git a/xmake/modules/devel/git/pull.lua b/xmake/modules/devel/git/pull.lua
index 9970f8dbc..412e6e757 100644
--- a/xmake/modules/devel/git/pull.lua
+++ b/xmake/modules/devel/git/pull.lua
@@ -58,18 +58,12 @@ function main(opt)
table.insert(argv, "--tags")
end
- -- enter repository directory
- local oldir = nil
- if opt.repodir then
- oldir = os.cd(opt.repodir)
- end
-
-- use proxy?
local envs
local proxy_conf = proxy.config()
if proxy_conf then
-- get proxy configuration from the current remote url
- local remoteinfo = try { function() return os.iorunv(git.program, {"remote", "-v"}) end }
+ local remoteinfo = try { function() return os.iorunv(git.program, {"remote", "-v"}, {curdir = opt.repodir}) end }
if remoteinfo then
for _, line in ipairs(remoteinfo:split('\n', {plain = true})) do
local splitinfo = line:split("%s+")
@@ -86,10 +80,5 @@ function main(opt)
end
-- pull it
- os.vrunv(git.program, argv, {envs = envs})
-
- -- leave repository directory
- if oldir then
- os.cd(oldir)
- end
+ os.vrunv(git.program, argv, {envs = envs, curdir = opt.repodir})
end
diff --git a/xmake/modules/devel/git/reset.lua b/xmake/modules/devel/git/reset.lua
index 28b984008..4ed798d25 100644
--- a/xmake/modules/devel/git/reset.lua
+++ b/xmake/modules/devel/git/reset.lua
@@ -71,17 +71,6 @@ function main(opt)
table.insert(argv, opt.commit)
end
- -- enter repository directory
- local oldir = nil
- if opt.repodir then
- oldir = os.cd(opt.repodir)
- end
-
-- reset it
- os.vrunv(git.program, argv)
-
- -- leave repository directory
- if oldir then
- os.cd(oldir)
- end
+ os.vrunv(git.program, argv, {curdir = opt.repodir})
end
diff --git a/xmake/modules/devel/git/submodule/update.lua b/xmake/modules/devel/git/submodule/update.lua
index 5d9323a02..511684c1c 100644
--- a/xmake/modules/devel/git/submodule/update.lua
+++ b/xmake/modules/devel/git/submodule/update.lua
@@ -58,37 +58,26 @@ function main(opt)
table.join2(argv, opt.paths)
end
- -- enter repository directory
- local oldir = nil
- if opt.repodir then
- oldir = os.cd(opt.repodir)
- end
-
-- enable long paths
local longpaths_old
local longpaths_changed = false
if opt.longpaths then
- local longpaths_old = try {function () return os.iorunv(git.program, {"config", "--get", "--global", "core.longpaths"}) end}
+ local longpaths_old = try {function () return os.iorunv(git.program, {"config", "--get", "--global", "core.longpaths"}, {curdir = opt.repodir}) end}
if not longpaths_old or not longpaths_old:find("true") then
- os.vrunv(git.program, {"config", "--global", "core.longpaths", "true"})
+ os.vrunv(git.program, {"config", "--global", "core.longpaths", "true"}, {curdir = opt.repodir})
longpaths_changed = true
end
end
-- submodule it
- os.vrunv(git.program, argv)
+ os.vrunv(git.program, argv, {curdir = opt.repodir})
-- restore old long paths configuration
if longpaths_changed then
if longpaths_old and longpaths_old:find("false") then
- os.vrunv(git.program, {"config", "--global", "core.longpaths", "false"})
+ os.vrunv(git.program, {"config", "--global", "core.longpaths", "false"}, {curdir = opt.repodir})
else
- os.vrunv(git.program, {"config", "--global", "--unset", "core.longpaths"})
+ os.vrunv(git.program, {"config", "--global", "--unset", "core.longpaths"}, {curdir = opt.repodir})
end
end
-
- -- leave repository directory
- if oldir then
- os.cd(oldir)
- end
end
diff --git a/xmake/modules/lib/detect/check_cxsnippets.lua b/xmake/modules/lib/detect/check_cxsnippets.lua
index aa728e27b..ea0e941d3 100644
--- a/xmake/modules/lib/detect/check_cxsnippets.lua
+++ b/xmake/modules/lib/detect/check_cxsnippets.lua
@@ -77,7 +77,11 @@ function _sourcecode(snippets, opt)
-- add includes
local sourcecode = ""
- for _, include in ipairs(opt.includes) do
+ local includes = table.wrap(opt.includes)
+ if opt.tryrun and opt.output then
+ table.insert(includes, "stdio.h")
+ end
+ for _, include in ipairs(includes) do
sourcecode = format("%s\n#include <%s>", sourcecode, include)
end
sourcecode = sourcecode .. "\n"
@@ -88,11 +92,13 @@ function _sourcecode(snippets, opt)
end
sourcecode = sourcecode .. "\n"
- -- add snippets
- for _, snippet in pairs(snippets) do
- sourcecode = sourcecode .. "\n" .. snippet
+ -- add snippets (build only)
+ if not opt.tryrun then
+ for _, snippet in pairs(snippets) do
+ sourcecode = sourcecode .. "\n" .. snippet
+ end
+ sourcecode = sourcecode .. "\n"
end
- sourcecode = sourcecode .. "\n"
-- enter main function
sourcecode = sourcecode .. "int main(int argc, char** argv)\n{\n"
@@ -102,10 +108,19 @@ function _sourcecode(snippets, opt)
sourcecode = format("%s\n %s;", sourcecode, _funccode(funcinfo))
end
- -- leave main function
- sourcecode = sourcecode .. "\n return 0;\n}\n"
-
- -- done
+ -- add snippets (tryrun)
+ if opt.tryrun then
+ for _, snippet in pairs(snippets) do
+ sourcecode = sourcecode .. "\n" .. snippet
+ end
+ if opt.output then
+ sourcecode = sourcecode .. "\nfflush(stdout);\n"
+ end
+ sourcecode = sourcecode .. "\n}\n" -- we need return exit code in snippet
+ else
+ -- leave main function
+ sourcecode = sourcecode .. "\n return 0;\n}\n"
+ end
return sourcecode
end
@@ -116,7 +131,8 @@ end
-- e.g.
-- { verbose = false, target = [target|option], sourcekind = "[cc|cxx]"
-- , types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}
--- , configs = {defines = "xx", cxflags = ""}}
+-- , configs = {defines = "xx", cxflags = ""}
+-- , tryrun = true, output = true}
--
-- funcs:
-- sigsetjmp
@@ -127,9 +143,9 @@ end
-- @return true or false
--
-- @code
--- local ok = check_cxsnippets("void test() {}")
--- local ok = check_cxsnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"})
--- local ok = check_cxsnippets({snippet_name = "void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"})
+-- local ok, output_or_errors = check_cxsnippets("void test() {}")
+-- local ok, output_or_errors = check_cxsnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"})
+-- local ok, output_or_errors = check_cxsnippets({snippet_name = "void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"})
-- @endcode
--
function main(snippets, opt)
@@ -189,19 +205,30 @@ function main(snippets, opt)
-- @note cannot cache result, all conditions will be changed
-- attempt to compile it
local errors = nil
- local ok = try
+ local ok, output = try
{
function ()
if option.get("diagnosis") then
cprint("${dim}> %s", compiler.compcmd(sourcefile, objectfile, opt))
end
compiler.compile(sourcefile, objectfile, opt)
- if #links > 0 then
+ if #links > 0 or opt.tryrun then
if option.get("diagnosis") then
cprint("${dim}> %s", linker.linkcmd("binary", {"cc", "cxx"}, objectfile, binaryfile, opt))
end
linker.link("binary", {"cc", "cxx"}, objectfile, binaryfile, opt)
end
+ if opt.tryrun then
+ if opt.output then
+ local output = os.iorun(binaryfile)
+ if output then
+ output = output:trim()
+ end
+ return true, output
+ else
+ os.vrun(binaryfile)
+ end
+ end
return true
end,
catch { function (errs) errors = errs end }
@@ -238,6 +265,6 @@ function main(snippets, opt)
if errors and option.get("diagnosis") and #tostring(errors) > 0 then
cprint("${color.warning}checkinfo:${clear dim} %s", errors)
end
- return ok
+ return ok, ok and output or errors
end
diff --git a/xmake/modules/lib/detect/features.lua b/xmake/modules/lib/detect/features.lua
index 614d8c592..8b9bde45b 100644
--- a/xmake/modules/lib/detect/features.lua
+++ b/xmake/modules/lib/detect/features.lua
@@ -79,12 +79,7 @@ function main(name, opt)
end
_g._checking = nil
- -- no features?
result = result or {}
-
- -- save result to cache
results[key] = result
-
- -- ok?
return result
end
diff --git a/xmake/modules/lib/detect/find_package.lua b/xmake/modules/lib/detect/find_package.lua
index 7b7ba7032..d3c9e57d1 100644
--- a/xmake/modules/lib/detect/find_package.lua
+++ b/xmake/modules/lib/detect/find_package.lua
@@ -24,6 +24,30 @@ import("core.project.config")
import("core.cache.detectcache")
import("package.manager.find_package")
+-- concat packages
+function _concat_packages(a, b)
+ local result = table.copy(a)
+ for k, v in pairs(b) do
+ local o = result[k]
+ if o ~= nil then
+ v = table.join(o, v)
+ end
+ result[k] = v
+ end
+ for k, v in pairs(result) do
+ if k == "links" then
+ if type(v) == "table" and #v > 1 then
+ -- we need ensure link orders when removing repeat values
+ v = table.reverse_unique(v)
+ end
+ else
+ v = table.unique(v)
+ end
+ result[k] = v
+ end
+ return result
+end
+
-- find package using the package manager
--
-- @param name the package name
@@ -113,5 +137,10 @@ function main(name, opt)
if not opt.version and result then
result.version = nil
end
+
+ -- register concat
+ if result and type(result) == "table" then
+ debug.setmetatable(result, {__concat = _concat_packages})
+ end
return result and result or nil
end
diff --git a/xmake/modules/lib/detect/pkgconfig.lua b/xmake/modules/lib/detect/pkgconfig.lua
index 9cd07a1e7..cf6b6d97d 100644
--- a/xmake/modules/lib/detect/pkgconfig.lua
+++ b/xmake/modules/lib/detect/pkgconfig.lua
@@ -24,7 +24,15 @@ import("core.project.target")
import("core.project.config")
import("lib.detect.find_file")
import("lib.detect.find_library")
-import("detect.tools.find_pkg_config")
+import("lib.detect.find_tool")
+
+-- get pkgconfig
+function _get_pkgconfig()
+ local pkgconfig = find_tool("pkg-config") or find_tool("pkgconf")
+ if pkgconfig then
+ return pkgconfig.program
+ end
+end
-- get version
--
@@ -34,7 +42,7 @@ import("detect.tools.find_pkg_config")
function version(name, opt)
-- attempt to add search paths from pkg-config
- local pkgconfig = find_pkg_config()
+ local pkgconfig = _get_pkgconfig()
if not pkgconfig then
return
end
@@ -46,7 +54,7 @@ function version(name, opt)
local configdirs_old = os.getenv("PKG_CONFIG_PATH")
local configdirs = table.wrap(opt.configdirs)
if #configdirs > 0 then
- os.setenv("PKG_CONFIG_PATH", unpack(configdirs))
+ os.setenv("PKG_CONFIG_PATH", table.unpack(configdirs))
end
-- get version
@@ -73,7 +81,7 @@ end
function variables(name, variables, opt)
-- attempt to add search paths from pkg-config
- local pkgconfig = find_pkg_config()
+ local pkgconfig = _get_pkgconfig()
if not pkgconfig then
return
end
@@ -85,7 +93,7 @@ function variables(name, variables, opt)
local configdirs_old = os.getenv("PKG_CONFIG_PATH")
local configdirs = table.wrap(opt.configdirs)
if #configdirs > 0 then
- os.setenv("PKG_CONFIG_PATH", unpack(configdirs))
+ os.setenv("PKG_CONFIG_PATH", table.unpack(configdirs))
end
-- get variable value
@@ -125,7 +133,7 @@ end
function libinfo(name, opt)
-- attempt to add search paths from pkg-config
- local pkgconfig = find_pkg_config()
+ local pkgconfig = _get_pkgconfig()
if not pkgconfig then
return
end
diff --git a/xmake/modules/net/ping.lua b/xmake/modules/net/ping.lua
index 5f555cccd..93e9b4bec 100644
--- a/xmake/modules/net/ping.lua
+++ b/xmake/modules/net/ping.lua
@@ -88,7 +88,7 @@ function main(hosts, opt)
end
-- trace
- vprint("pinging for the host(%s) ... %d ms", host, timeval)
+ vprint("pinging for the host(%s) ... %d ms", host, math.floor(timeval))
end
end
end, {total = #hosts})
diff --git a/xmake/modules/package/manager/apt/find_package.lua b/xmake/modules/package/manager/apt/find_package.lua
index f27968c0e..e2617b4ec 100644
--- a/xmake/modules/package/manager/apt/find_package.lua
+++ b/xmake/modules/package/manager/apt/find_package.lua
@@ -24,26 +24,8 @@ import("core.project.config")
import("core.project.target")
import("lib.detect.find_tool")
--- find package using the dpkg package manager
---
--- @param name the package name
--- @param opt the options, e.g. {verbose = true, version = "1.12.0")
---
-function main(name, opt)
-
- -- check
- opt = opt or {}
- if not is_host(opt.plat) or os.arch() ~= opt.arch then
- return
- end
-
- -- find dpkg
- local dpkg = find_tool("dpkg")
- if not dpkg then
- return
- end
-
- -- find package
+-- find package
+function _find_package(dpkg, name, opt)
local result = nil
local listinfo = try {function () return os.iorunv(dpkg.program, {"--listfiles", name}) end}
if listinfo then
@@ -51,14 +33,11 @@ function main(name, opt)
line = line:trim()
-- get includedirs
- -- we need not add it, gcc/clang will use /usr/ as default sysroot
- --[[
local pos = line:find("include/", 1, true)
if pos then
+ -- we need not add includedirs, gcc/clang will use /usr/ as default sysroot
result = result or {}
- result.includedirs = result.includedirs or {}
- table.insert(result.includedirs, line:sub(1, pos + 7))
- end]]
+ end
-- get linkdirs and links
if line:endswith(".a") or line:endswith(".so") then
@@ -67,12 +46,30 @@ function main(name, opt)
result.linkdirs = result.linkdirs or {}
result.libfiles = result.libfiles or {}
table.insert(result.linkdirs, path.directory(line))
- table.insert(result.links, target.linkname(path.filename(line)))
+ table.insert(result.links, target.linkname(path.filename(line), {plat = opt.plat}))
table.insert(result.libfiles, path.join(path.directory(line), path.filename(line)))
end
end
end
+ -- meta/alias package? e.g. libboost-dev -> libboost1.74-dev
+ -- @see https://github.com/xmake-io/xmake/issues/1786
+ if not result then
+ local statusinfo = try {function () return os.iorunv(dpkg.program, {"--status", name}) end}
+ if statusinfo then
+ for _, line in ipairs(statusinfo:split("\n", {plain = true})) do
+ -- parse depends, e.g. Depends: libboost1.74-dev
+ if line:startswith("Depends:") then
+ local depends = line:sub(9):split("%s+")
+ if #depends == 1 then
+ return _find_package(dpkg, depends[1], opt)
+ end
+ break
+ end
+ end
+ end
+ end
+
-- remove repeat
if result then
if result.links then
@@ -87,3 +84,26 @@ function main(name, opt)
end
return result
end
+
+-- find package using the dpkg package manager
+--
+-- @param name the package name
+-- @param opt the options, e.g. {verbose = true, version = "1.12.0")
+--
+function main(name, opt)
+
+ -- check
+ opt = opt or {}
+ if not is_host(opt.plat) or os.arch() ~= opt.arch then
+ return
+ end
+
+ -- find dpkg
+ local dpkg = find_tool("dpkg")
+ if not dpkg then
+ return
+ end
+
+ -- find package
+ return _find_package(dpkg, name, opt)
+end
diff --git a/xmake/modules/package/manager/brew/find_package.lua b/xmake/modules/package/manager/brew/find_package.lua
index 49db5a464..9706bfd8e 100644
--- a/xmake/modules/package/manager/brew/find_package.lua
+++ b/xmake/modules/package/manager/brew/find_package.lua
@@ -67,14 +67,16 @@ function main(name, opt)
-- find package from pkg-config/*.pc, attempt to find it from `brew --prefix`/package first
local result = nil
- local pcfile = find_file(pcname .. ".pc", path.join(brew_pkg_rootdir, nameinfo[1], "*/lib/pkgconfig"))
+ local pcfile = find_file(pcname .. ".pc", path.join(brew_pkg_rootdir, nameinfo[1], "*/lib/pkgconfig")) or
+ find_file(pcname .. ".pc", path.join(brew_pkg_rootdir, nameinfo[1], "*/share/pkgconfig"))
if not pcfile then
-- attempt to find it from `brew --prefix package`
local brew = find_tool("brew")
local brew_pkgdir = brew and try {function () return os.iorunv(brew.program, {"--prefix", nameinfo[1]}) end}
if brew_pkgdir then
brew_pkgdir = brew_pkgdir:trim()
- pcfile = find_file(pcname .. ".pc", path.join(brew_pkgdir, "lib/pkgconfig"))
+ pcfile = find_file(pcname .. ".pc", path.join(brew_pkgdir, "lib/pkgconfig")) or
+ find_file(pcname .. ".pc", path.join(brew_pkgdir, "share/pkgconfig"))
end
end
if pcfile then
@@ -97,11 +99,11 @@ function main(name, opt)
if pkgdir then
local links = {}
for _, libfile in ipairs(os.files(path.join(pkgdir, "lib", "*.a"))) do
- table.insert(links, target.linkname(path.filename(libfile)))
+ table.insert(links, target.linkname(path.filename(libfile), {plat = opt.plat}))
end
for _, libfile in ipairs(os.files(path.join(pkgdir, "lib", opt.plat == "macosx" and "*.dylib" or "*.so"))) do
if not os.islink(libfile) then
- table.insert(links, target.linkname(path.filename(libfile)))
+ table.insert(links, target.linkname(path.filename(libfile), {plat = opt.plat}))
end
end
opt.links = links
diff --git a/xmake/modules/package/manager/cargo/configurations.lua b/xmake/modules/package/manager/cargo/configurations.lua
new file mode 100644
index 000000000..a3f85a0ea
--- /dev/null
+++ b/xmake/modules/package/manager/cargo/configurations.lua
@@ -0,0 +1,28 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file configurations.lua
+--
+
+-- get configurations
+function main()
+ return
+ {
+ features = {description = "set the features of dependency."},
+ default_features = {description = "enables or disables any defaults provided by the dependency.", default = true},
+ }
+end
diff --git a/xmake/modules/package/manager/cargo/find_package.lua b/xmake/modules/package/manager/cargo/find_package.lua
new file mode 100644
index 000000000..7fd151d5c
--- /dev/null
+++ b/xmake/modules/package/manager/cargo/find_package.lua
@@ -0,0 +1,58 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_package.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.semver")
+import("core.project.config")
+import("core.project.target")
+import("lib.detect.find_tool")
+import("lib.detect.find_file")
+
+-- find package using the cargo package manager
+--
+-- @param name the package name
+-- @param opt the options, e.g. {verbose = true, require_version = "1.12.x")
+--
+function main(name, opt)
+ local frameworkdirs
+ local frameworks
+ local librarydir = path.join(opt.installdir, "lib")
+ local libfiles = os.files(path.join(librarydir, "*.rlib"))
+ for _, libraryfile in ipairs(libfiles) do
+ local filename = path.filename(libraryfile)
+ if filename:startswith("lib" .. name .. "-") then
+ frameworkdirs = frameworkdirs or {}
+ frameworks = frameworks or {}
+ table.insert(frameworkdirs, librarydir)
+ table.insert(frameworks, libraryfile)
+ break
+ end
+ end
+ local result
+ if frameworks and frameworkdirs then
+ result = result or {}
+ result.libfiles = libfiles
+ result.frameworkdirs = frameworkdirs
+ result.frameworks = frameworks
+ result.version = opt.require_version
+ end
+ return result
+end
diff --git a/xmake/modules/package/manager/cargo/install_package.lua b/xmake/modules/package/manager/cargo/install_package.lua
new file mode 100644
index 000000000..9ea709dd7
--- /dev/null
+++ b/xmake/modules/package/manager/cargo/install_package.lua
@@ -0,0 +1,95 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file install_package.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.config")
+import("lib.detect.find_tool")
+
+-- install package
+--
+-- e.g.
+-- add_requires("cargo::base64")
+-- add_requires("cargo::base64 0.13.0")
+-- add_requires("cargo::flate2 1.0.17", {configs = {features = {"zlib"}, ["default-features"] = false}})
+--
+-- @param name the package name, e.g. cargo::base64
+-- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = , require_version = "x.x.x"}
+--
+-- @return true or false
+--
+function main(name, opt)
+
+ -- find cargo
+ local cargo = find_tool("cargo")
+ if not cargo then
+ raise("cargo not found!")
+ end
+
+ -- get required version
+ opt = opt or {}
+ local configs = opt.configs or {}
+ local require_version = opt.require_version
+ if not require_version or require_version == "latest" then
+ require_version = "*"
+ end
+
+ -- build dependencies
+ local sourcedir = path.join(opt.cachedir, "source")
+ local cargotoml = path.join(sourcedir, "Cargo.toml")
+ os.tryrm(sourcedir)
+ local tomlfile = io.open(cargotoml, "w")
+ tomlfile:print("[package]")
+ tomlfile:print("name = \"cargodeps\"")
+ tomlfile:print("version = \"0.1.0\"")
+ tomlfile:print("edition = \"2018\"")
+ tomlfile:print("")
+ tomlfile:print("[dependencies]")
+ local features = configs.features
+ if features then
+ features = table.wrap(features)
+ tomlfile:print("%s = {version = \"%s\", features = [\"%s\"], default-features = %s}", name, require_version, table.concat(features, "\", \""), configs.default_features)
+ else
+ tomlfile:print("%s = \"%s\"", name, require_version)
+ end
+ tomlfile:close()
+
+ -- generate main.rs
+ io.writefile(path.join(sourcedir, "src", "main.rs"), [[
+fn main() {
+ println!("Hello, world!");
+}
+ ]])
+
+ -- do build
+ local argv = {"build"}
+ if opt.mode ~= "debug" then
+ table.insert(argv, "--release")
+ end
+ if option.get("verbose") then
+ table.insert(argv, option.get("diagnosis") and "-vv" or "-v")
+ end
+ os.vrunv(cargo.program, argv, {curdir = sourcedir})
+
+ -- do install
+ local installdir = opt.installdir
+ os.tryrm(path.join(installdir, "lib"))
+ os.vcp(path.join(sourcedir, "target", opt.mode == "debug" and "debug" or "release", "deps"), path.join(installdir, "lib"))
+end
diff --git a/xmake/modules/package/manager/clib/configurations.lua b/xmake/modules/package/manager/clib/configurations.lua
new file mode 100644
index 000000000..4f59ea70d
--- /dev/null
+++ b/xmake/modules/package/manager/clib/configurations.lua
@@ -0,0 +1,30 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author Adel Vilkov (aka RaZeR-RBI)
+-- @file configurations.lua
+--
+
+-- get configurations
+function main()
+ return
+ {
+ save = {description = "save dependency in project's package.json", default = false, type = "boolean"},
+ save_dev = {description = "save as development dependency in project's package.json", default = false, type = "boolean"},
+ outputdir = {description = "package installation directory relative to project root", default = "clib"},
+ }
+end
+
diff --git a/xmake/modules/package/manager/clib/install_package.lua b/xmake/modules/package/manager/clib/install_package.lua
index 1b61af5b4..0257ff8fe 100644
--- a/xmake/modules/package/manager/clib/install_package.lua
+++ b/xmake/modules/package/manager/clib/install_package.lua
@@ -23,42 +23,35 @@ import("core.base.option")
import("core.project.config")
import("lib.detect.find_tool")
--- get configurations
-function configurations()
- return
- {
- save = {description = "save dependency in project's package.json", default = false, type = "boolean"},
- save_dev = {description = "save as development dependency in project's package.json", default = false, type = "boolean"},
- outputdir = {description = "package installation directory relative to project root", default = "clib"},
- }
-end
-
-- install package
-- @param name the package name, e.g. clib::clibs/[email protected]
-- @param opt the options, e.g. { verbose = true,
--- settings = {outputdir = "clib", save = false, save_dev = false}}
+-- configs = {outputdir = "clib", save = false, save_dev = false}}
--
-- @return true or false
--
function main(name, opt)
+
-- find clib
local clib = find_tool("clib")
if not clib then
raise("clib not found!")
end
+ opt = opt or {}
+ local configs = opt.configs or {}
local argv = {"install", name}
- local abs_out = path.join(os.projectdir(), opt.outputdir)
+ local abs_out = path.join(os.projectdir(), configs.outputdir)
dprint("installing %s to %s", name, abs_out)
table.insert(argv, "-o " .. abs_out)
if not option.get("verbose") then
table.insert(argv, "-q")
end
- if opt.save then
+ if configs.save then
table.insert(argv, "--save")
end
- if opt.save_dev then
+ if configs.save_dev then
table.insert(argv, "--save-dev")
end
diff --git a/xmake/modules/package/manager/cmake/configurations.lua b/xmake/modules/package/manager/cmake/configurations.lua
new file mode 100644
index 000000000..e65525f6d
--- /dev/null
+++ b/xmake/modules/package/manager/cmake/configurations.lua
@@ -0,0 +1,31 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file configurations.lua
+--
+
+-- get configurations
+function main()
+ return
+ {
+ components = {description = "Set the cmake package components, e.g. {\"regex\", \"system\"}"},
+ moduledirs = {description = "Set the cmake modules directories."},
+ presets = {description = "Set the preset values, e.g. {Boost_USE_STATIC_LIB = true}"},
+ envs = {description = "Set the run environments of cmake, e.g. {CMAKE_PREFIX_PATH = \"xxx\"}"},
+ }
+end
+
diff --git a/xmake/modules/package/manager/cmake/find_package.lua b/xmake/modules/package/manager/cmake/find_package.lua
new file mode 100644
index 000000000..d9abd6b00
--- /dev/null
+++ b/xmake/modules/package/manager/cmake/find_package.lua
@@ -0,0 +1,282 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_package.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.target")
+import("lib.detect.find_tool")
+
+-- find package
+function _find_package(cmake, name, opt)
+
+ -- get work directory
+ local workdir = os.tmpfile() .. ".dir"
+ os.tryrm(workdir)
+ os.mkdir(workdir)
+ io.writefile(path.join(workdir, "test.cpp"), "")
+
+ -- generate CMakeLists.txt
+ local cmakefile = io.open(path.join(workdir, "CMakeLists.txt"), "w")
+ if cmake.version then
+ cmakefile:print("cmake_minimum_required(VERSION %s)", cmake.version)
+ end
+ cmakefile:print("project(find_package)")
+
+ -- e.g. OpenCV 4.1.1, Boost COMPONENTS regex system
+ local requirestr = name
+ local configs = opt.configs or {}
+ if opt.required_version then
+ requirestr = requirestr .. " " .. opt.required_version
+ end
+ -- use opt.components is for backward compatibility
+ local components = configs.components or opt.components
+ if components then
+ requirestr = requirestr .. " COMPONENTS"
+ for _, component in ipairs(components) do
+ requirestr = requirestr .. " " .. component
+ end
+ end
+ local moduledirs = configs.moduledirs or opt.moduledirs
+ if moduledirs then
+ for _, moduledir in ipairs(moduledirs) do
+ cmakefile:print("add_cmake_modules(%s)", moduledir)
+ end
+ end
+ -- e.g. set(Boost_USE_STATIC_LIB ON)
+ local presets = configs.presets or opt.presets
+ if presets then
+ for k, v in pairs(presets) do
+ if type(v) == "boolean" then
+ cmakefile:print("set(%s %s)", k, v and "ON" or "OFF")
+ else
+ cmakefile:print("set(%s %s)", k, tostring(v))
+ end
+ end
+ end
+ cmakefile:print("find_package(%s REQUIRED)", requirestr)
+ cmakefile:print("if(%s_FOUND)", name)
+ cmakefile:print(" add_executable(%s test.cpp)", name)
+ cmakefile:print(" target_include_directories(%s PRIVATE ${%s_INCLUDE_DIR} ${%s_INCLUDE_DIRS})",
+ name, name, name)
+ cmakefile:print(" target_include_directories(%s PRIVATE ${%s_INCLUDE_DIR} ${%s_INCLUDE_DIRS})",
+ name, name:upper(), name:upper())
+ cmakefile:print(" target_include_directories(%s PRIVATE ${%s_CXX_INCLUDE_DIRS})",
+ name, name)
+ cmakefile:print(" target_link_libraries(%s ${%s_LIBRARY} ${%s_LIBRARIES} ${%s_LIBS})",
+ name, name, name, name)
+ cmakefile:print(" target_link_libraries(%s ${%s_LIBRARY} ${%s_LIBRARIES} ${%s_LIBS})",
+ name, name:upper(), name:upper(), name:upper())
+ cmakefile:print("endif(%s_FOUND)", name)
+ cmakefile:close()
+
+ -- run cmake
+ local envs = configs.envs or opt.envs
+ try {function() return os.vrunv(cmake.program, {workdir}, {curdir = workdir, envs = envs}) end}
+
+ -- pares defines and includedirs for macosx/linux
+ local links
+ local linkdirs
+ local libfiles
+ local defines
+ local includedirs
+ local ldflags
+ local flagsfile = path.join(workdir, "CMakeFiles", name .. ".dir", "flags.make")
+ if os.isfile(flagsfile) then
+ local flagsdata = io.readfile(flagsfile)
+ if flagsdata then
+ if option.get("diagnosis") then
+ vprint(flagsdata)
+ end
+ for _, line in ipairs(flagsdata:split("\n", {plain = true})) do
+ if line:find("CXX_INCLUDES =", 1, true) then
+ local has_include = false
+ local flags = os.argv(line:split("=", {plain = true})[2]:trim())
+ for _, flag in ipairs(flags) do
+ if has_include or (flag:startswith("-I") and #flag > 2) then
+ local includedir = has_include and flag or flag:sub(3)
+ if includedir and os.isdir(includedir) then
+ includedirs = includedirs or {}
+ table.insert(includedirs, includedir)
+ end
+ has_include = false
+ elseif flag == "-isystem" or flag == "-I" then
+ has_include = true
+ end
+ end
+ elseif line:find("CXX_DEFINES =", 1, true) then
+ local flags = os.argv(line:split("=", {plain = true})[2]:trim())
+ for _, flag in ipairs(flags) do
+ if flag:startswith("-D") and #flag > 2 then
+ local define = flag:sub(3)
+ if define then
+ defines = defines or {}
+ table.insert(defines, define)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- parse links and linkdirs for macosx/linux
+ local linkfile = path.join(workdir, "CMakeFiles", name .. ".dir", "link.txt")
+ if os.isfile(linkfile) then
+ local linkdata = io.readfile(linkfile)
+ if linkdata then
+ if option.get("diagnosis") then
+ vprint(linkdata)
+ end
+ for _, line in ipairs(os.argv(linkdata)) do
+ local is_ldflags = false
+ local is_library = false
+ for _, suffix in ipairs({".so", ".dylib", ".dylib", ".tbd", ".lib"}) do
+ if line:startswith("-Wl,") then
+ is_ldflags = true
+ break
+ elseif line:find(suffix, 1, true) then
+ is_library = true
+ break
+ end
+ end
+ if is_ldflags then
+ ldflags = ldflags or {}
+ table.insert(ldflags, line)
+ elseif is_library then
+ -- strip library version suffix, e.g. libxxx.so.1.1 -> libxxx.so
+ if line:find(".so", 1, true) then
+ line = line:gsub("lib(.-)%.so%..+$", "lib%1.so")
+ end
+
+ -- get libfiles
+ if os.isfile(line) then
+ libfiles = libfiles or {}
+ table.insert(libfiles, line)
+ end
+
+ -- get links and linkdirs
+ local linkdir = path.directory(line)
+ if linkdir ~= "." then
+ linkdirs = linkdirs or {}
+ table.insert(linkdirs, linkdir)
+ end
+ local link = target.linkname(path.filename(line))
+ if link then
+ links = links or {}
+ table.insert(links, link)
+ end
+ end
+ end
+ end
+ end
+
+ -- pares includedirs and links/linkdirs for windows
+ local vcprojfile = path.join(workdir, name .. ".vcxproj")
+ if os.isfile(vcprojfile) then
+ local vcprojdata = io.readfile(vcprojfile)
+ if vcprojdata then
+ for _, line in ipairs(vcprojdata:split("\n", {plain = true})) do
+ local values = line:match("<AdditionalIncludeDirectories>(.+);%%%(AdditionalIncludeDirectories%)</AdditionalIncludeDirectories>")
+ if values then
+ includedirs = includedirs or {}
+ table.join2(includedirs, path.splitenv(values))
+ end
+
+ values = line:match("<AdditionalDependencies>(.+)</AdditionalDependencies>")
+ if not values then
+ -- we need also parse libraries from here
+ -- https://github.com/xmake-io/xmake/issues/1822
+ values = line:match("<ImportLibrary>(.+)</ImportLibrary>")
+ end
+ if values then
+ for _, library in ipairs(path.splitenv(values)) do
+ -- get libfiles
+ if os.isfile(library) then
+ libfiles = libfiles or {}
+ table.insert(libfiles, library)
+ end
+
+ -- get links and linkdirs
+ local linkdir = path.directory(library)
+ linkdir = path.translate(linkdir)
+ if linkdir ~= "." and not linkdir:startswith(workdir) then
+ linkdirs = linkdirs or {}
+ table.insert(linkdirs, linkdir)
+ local link = target.linkname(path.filename(library))
+ if link then
+ links = links or {}
+ table.insert(links, link)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- remove work directory
+ os.tryrm(workdir)
+
+ -- get results
+ if links or includedirs then
+ local results = {}
+ results.links = table.reverse_unique(links)
+ results.ldflags = table.reverse_unique(ldflags)
+ results.linkdirs = table.unique(linkdirs)
+ results.defines = table.unique(defines)
+ results.libfiles = table.unique(libfiles)
+ results.includedirs = table.unique(includedirs)
+ print(results)
+ return results
+ end
+end
+
+-- find package using the cmake package manager
+--
+-- e.g.
+--
+-- find_package("cmake::ZLIB")
+-- find_package("cmake::OpenCV", {required_version = "4.1.1"})
+-- find_package("cmake::Boost", {configs = {components = {"regex", "system"}, presets = {Boost_USE_STATIC_LIB = true}}})
+-- find_package("cmake::Foo", {configs = {moduledirs = "xxx"}})
+--
+-- we can use add_requires with {system = true}
+--
+-- add_requires("cmake::ZLIB", {system = true})
+-- add_requires("cmake::OpenCV 4.1.1", {system = true})
+-- add_requires("cmake::Boost", {configs = {components = {"regex", "system"}, presets = {Boost_USE_STATIC_LIB = true}}})
+-- add_requires("cmake::Foo", {configs = {moduledirs = "xxx"}})
+--
+-- @param name the package name
+-- @param opt the options, e.g. {verbose = true, required_version = "1.0",
+-- configs = {
+-- components = {"regex", "system"},
+-- moduledirs = "xxx",
+-- presets = {Boost_USE_STATIC_LIB = true},
+-- envs = {CMAKE_PREFIX_PATH = "xxx"}})
+--
+function main(name, opt)
+ opt = opt or {}
+ local cmake = find_tool("cmake", {version = true})
+ if not cmake then
+ return
+ end
+ return _find_package(cmake, name, opt)
+end
diff --git a/xmake/modules/package/manager/conan/configurations.lua b/xmake/modules/package/manager/conan/configurations.lua
new file mode 100644
index 000000000..b4ed38fc3
--- /dev/null
+++ b/xmake/modules/package/manager/conan/configurations.lua
@@ -0,0 +1,33 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file configurations.lua
+--
+
+-- get configurations
+function main()
+ return
+ {
+ build = {description = "Use it to choose if you want to build from sources.", default = "missing", values = {"all", "never", "missing", "outdated"}},
+ remote = {description = "Set the conan remote server."},
+ options = {description = "Set the options values, e.g. OpenSSL:shared=True"},
+ imports = {description = "Set the imports for conan."},
+ settings = {description = "Set the build settings for conan."},
+ build_requires = {description = "Set the build requires for conan.", default = "xmake_generator/0.1.0@bincrafters/testing"}
+ }
+end
+
diff --git a/xmake/modules/package/manager/conan/find_package.lua b/xmake/modules/package/manager/conan/find_package.lua
index d372e2a75..fca3d3891 100644
--- a/xmake/modules/package/manager/conan/find_package.lua
+++ b/xmake/modules/package/manager/conan/find_package.lua
@@ -59,7 +59,7 @@ end
-- find package using the conan package manager
--
-- @param name the package name
--- @param opt the options, e.g. {verbose = true, version = "1.12.x")
+-- @param opt the options, e.g. {verbose = true)
--
function main(name, opt)
diff --git a/xmake/modules/package/manager/conan/install_package.lua b/xmake/modules/package/manager/conan/install_package.lua
index 97af3b4b8..9f5a52a18 100644
--- a/xmake/modules/package/manager/conan/install_package.lua
+++ b/xmake/modules/package/manager/conan/install_package.lua
@@ -49,15 +49,15 @@ function _conan_get_build_directory(name)
end
-- generate conanfile.txt
-function _conan_generate_conanfile(name, opt)
+function _conan_generate_conanfile(name, configs)
-- trace
dprint("generate %s ..", path.join(_conan_get_build_directory(name), "conanfile.txt"))
-- get conan options, imports and build_requires
- local options = table.wrap(opt.options)
- local imports = table.wrap(opt.imports)
- local build_requires = table.wrap(opt.build_requires)
+ local options = table.wrap(configs.options)
+ local imports = table.wrap(configs.imports)
+ local build_requires = table.wrap(configs.build_requires)
-- @see https://docs.conan.io/en/latest/systems_cross_building/cross_building.html
-- generate it
@@ -109,30 +109,22 @@ function _conan_install_xmake_generator(conan)
end
end
--- get configurations
-function configurations()
- return
- {
- build = {description = "use it to choose if you want to build from sources.", default = "missing", values = {"all", "never", "missing", "outdated"}},
- remote = {description = "Set the conan remote server."},
- options = {description = "Set the options values, e.g. OpenSSL:shared=True"},
- imports = {description = "Set the imports for conan."},
- settings = {description = "Set the build settings for conan."},
- build_requires = {description = "Set the build requires for conan.", default = "xmake_generator/0.1.0@bincrafters/testing"}
- }
-end
-
-- install package
--
-- @param name the package name, e.g. conan::OpenSSL/1.0.2n@conan/stable
-- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = ,
--- remote = "", build = "all", options = {}, imports = {}, build_requires = {},
--- settings = {"compiler=Visual Studio", "compiler.version=10", "compiler.runtime=MD"}}
+-- configs = {
+-- remote = "", build = "all", options = {}, imports = {}, build_requires = {},
+-- settings = {"compiler=Visual Studio", "compiler.version=10", "compiler.runtime=MD"}}}
--
-- @return true or false
--
function main(name, opt)
+ -- get configs
+ opt = opt or {}
+ local configs = opt.configs or {}
+
-- find conan
local conan = find_tool("conan")
if not conan then
@@ -155,15 +147,15 @@ function main(name, opt)
_conan_install_xmake_generator(conan)
-- generate conanfile.txt
- _conan_generate_conanfile(name, opt)
+ _conan_generate_conanfile(name, configs)
-- install package
local argv = {"install", "."}
- if opt.build then
- if opt.build == "all" then
+ if configs.build then
+ if configs.build == "all" then
table.insert(argv, "--build")
else
- table.insert(argv, "--build=" .. opt.build)
+ table.insert(argv, "--build=" .. configs.build)
end
end
@@ -241,15 +233,15 @@ function main(name, opt)
end
-- set custom settings
- for _, setting in ipairs(opt.settings) do
+ for _, setting in ipairs(configs.settings) do
table.insert(argv, "-s")
table.insert(argv, setting)
end
-- set remote
- if opt.remote then
+ if configs.remote then
table.insert(argv, "-r")
- table.insert(argv, opt.remote)
+ table.insert(argv, configs.remote)
end
-- TODO set environments
diff --git a/xmake/modules/package/manager/conda/find_package.lua b/xmake/modules/package/manager/conda/find_package.lua
index 5d2634d63..1e09072d4 100644
--- a/xmake/modules/package/manager/conda/find_package.lua
+++ b/xmake/modules/package/manager/conda/find_package.lua
@@ -52,7 +52,7 @@ end
-- find package using the conda package manager
--
-- @param name the package name
--- @param opt the options, e.g. {verbose = true, version = "1.12.0")
+-- @param opt the options, e.g. {verbose = true, require_version = "1.12.0")
--
function main(name, opt)
@@ -124,7 +124,7 @@ function main(name, opt)
result.linkdirs = result.linkdirs or {}
result.libfiles = result.libfiles or {}
table.insert(result.linkdirs, path.join(packagedir, path.directory(line)))
- table.insert(result.links, target.linkname(path.filename(line)))
+ table.insert(result.links, target.linkname(path.filename(line), {plat = opt.plat}))
table.insert(result.libfiles, path.join(packagedir, path.directory(line), path.filename(line)))
end
diff --git a/xmake/modules/package/manager/dub/find_package.lua b/xmake/modules/package/manager/dub/find_package.lua
index 55ad2d6ef..5d49d695e 100644
--- a/xmake/modules/package/manager/dub/find_package.lua
+++ b/xmake/modules/package/manager/dub/find_package.lua
@@ -30,7 +30,7 @@ import("lib.detect.find_file")
-- find package using the dub package manager
--
-- @param name the package name
--- @param opt the options, e.g. {verbose = true, version = "1.12.x")
+-- @param opt the options, e.g. {verbose = true, require_version = "1.12.x")
--
function main(name, opt)
@@ -67,7 +67,7 @@ function main(name, opt)
if pkgdir then
local links = {}
for _, libraryfile in ipairs(os.files(path.join(pkgdir, libpattern))) do
- table.insert(links, target.linkname(path.filename(libraryfile)))
+ table.insert(links, target.linkname(path.filename(libraryfile), {plat = opt.plat}))
end
local includedirs = {}
local dubjson = path.join(pkgdir, "dub.json")
diff --git a/xmake/modules/package/manager/dub/install_package.lua b/xmake/modules/package/manager/dub/install_package.lua
index 84406af5f..d459bfd92 100644
--- a/xmake/modules/package/manager/dub/install_package.lua
+++ b/xmake/modules/package/manager/dub/install_package.lua
@@ -26,7 +26,7 @@ import("lib.detect.find_tool")
-- install package
--
-- @param name the package name, e.g. dub::log
--- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = , require_version = "x.x.x", buildhash = "xxxxxx"}
+-- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = , require_version = "x.x.x"}
--
-- @return true or false
--
diff --git a/xmake/modules/package/manager/find_package.lua b/xmake/modules/package/manager/find_package.lua
index 41c110796..7d82043b2 100644
--- a/xmake/modules/package/manager/find_package.lua
+++ b/xmake/modules/package/manager/find_package.lua
@@ -174,7 +174,7 @@ function main(name, opt)
opt.mode = opt.mode or config.mode() or "release"
-- get package manager name
- local manager_name, package_name = unpack(name:split("::", {plain = true, strict = true}))
+ local manager_name, package_name = table.unpack(name:split("::", {plain = true, strict = true}))
if package_name == nil then
package_name = manager_name
manager_name = nil
@@ -184,7 +184,7 @@ function main(name, opt)
-- get package name and require version
local require_version = nil
- package_name, require_version = unpack(package_name:trim():split("%s"))
+ package_name, require_version = table.unpack(package_name:trim():split("%s"))
opt.require_version = require_version or opt.require_version
-- find package
diff --git a/xmake/modules/package/manager/install_package.lua b/xmake/modules/package/manager/install_package.lua
index 1c5d5ab07..05e13ed27 100644
--- a/xmake/modules/package/manager/install_package.lua
+++ b/xmake/modules/package/manager/install_package.lua
@@ -93,7 +93,7 @@ function main(name, opt)
opt.mode = opt.mode or config.mode() or "release"
-- get package manager name
- local manager_name, package_name = unpack(name:split("::", {plain = true, strict = true}))
+ local manager_name, package_name = table.unpack(name:split("::", {plain = true, strict = true}))
if package_name == nil then
package_name = manager_name
manager_name = nil
@@ -103,7 +103,7 @@ function main(name, opt)
-- get package name and require version
local require_version = nil
- package_name, require_version = unpack(package_name:trim():split("%s"))
+ package_name, require_version = table.unpack(package_name:trim():split("%s"))
opt.require_version = require_version or opt.require_version
-- do install package
diff --git a/xmake/modules/package/manager/nimble/find_package.lua b/xmake/modules/package/manager/nimble/find_package.lua
new file mode 100644
index 000000000..c39d6ed34
--- /dev/null
+++ b/xmake/modules/package/manager/nimble/find_package.lua
@@ -0,0 +1,67 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_package.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.semver")
+import("core.project.config")
+import("core.project.target")
+import("lib.detect.find_tool")
+import("lib.detect.find_file")
+
+-- find package using the nimble package manager
+--
+-- @param name the package name
+-- @param opt the options, e.g. {verbose = true, require_version = "1.12.x")
+--
+function main(name, opt)
+
+ -- find nimble
+ local nimble = find_tool("nimble")
+ if not nimble then
+ raise("nimble not found!")
+ end
+
+ -- find it from all installed package list
+ local result
+ local list = os.iorunv(nimble.program, {"list", "-i"})
+ for _, line in ipairs(list:split("\n", {plain = true})) do
+ local splitinfo = line:split("%s+")
+ local package_name = splitinfo[1]
+ local package_version = splitinfo[2]
+ if package_name == name and package_version then
+ if package_version then
+ package_version = package_version:match("%[(.+)%]")
+ end
+ if opt.require_version then
+ if package_version and (opt.require_version == "latest" or semver.match(package_version, 1, opt.require_version)) then
+ result = {version = package_version}
+ break
+ end
+ else
+ result = {}
+ break
+ end
+ end
+ end
+ -- @note we need not return links and includedirs information,
+ -- because it's nim source code package and nim will find them automatically
+ return result
+end
diff --git a/xmake/modules/package/manager/nimble/install_package.lua b/xmake/modules/package/manager/nimble/install_package.lua
new file mode 100644
index 000000000..326758e8c
--- /dev/null
+++ b/xmake/modules/package/manager/nimble/install_package.lua
@@ -0,0 +1,58 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file install_package.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.config")
+import("lib.detect.find_tool")
+
+-- install package
+--
+-- e.g.
+-- add_requires("nimble::zip")
+-- add_requires("nimble::zip >0.3")
+-- add_requires("nimble::zip 0.3.1")
+--
+-- @param name the package name, e.g. nimble::zip
+-- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = , require_version = "x.x.x"}
+--
+-- @return true or false
+--
+function main(name, opt)
+
+ -- find nimble
+ local nimble = find_tool("nimble")
+ if not nimble then
+ raise("nimble not found!")
+ end
+
+ -- install the given package
+ local argv = {"install", "-y"}
+ if option.get("verbose") then
+ table.insert(argv, "--verbose")
+ end
+ local require_str = name
+ if opt.require_version and opt.require_version ~= "latest" and opt.require_version ~= "master" then
+ name = name .. "@"
+ name = name .. opt.require_version
+ end
+ table.insert(argv, name)
+ os.vrunv(nimble.program, argv)
+end
diff --git a/xmake/modules/package/manager/pacman/find_package.lua b/xmake/modules/package/manager/pacman/find_package.lua
index 4b2be0403..c47edaad6 100644
--- a/xmake/modules/package/manager/pacman/find_package.lua
+++ b/xmake/modules/package/manager/pacman/find_package.lua
@@ -20,9 +20,74 @@
-- imports
import("core.base.option")
+import("core.project.target")
import("lib.detect.find_tool")
import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
+-- get result from list of file inside pacman package
+function _find_package_from_list(list, name, pacman, opt)
+
+ -- mingw + pacman = cygpath available
+ local cygpath = nil
+ if is_subhost("msys") and opt.plat == "mingw" then
+ cygpath = find_tool("cygpath")
+ if not cygpath then
+ return
+ end
+ end
+
+ -- iterate over each file path inside the pacman package
+ local result = {includedirs = {}, linkdirs = {}, links = {}}
+ for _, line in ipairs(list:split('\n', {plain = true})) do -- on msys cygpath should be used to convert local path to windows path
+ line = line:trim():split('%s+')[2]
+ if line:find("/include/", 1, true) and (line:endswith(".h") or line:endswith(".hpp")) then
+ local hpath = line
+ if is_subhost("msys") and opt.plat == "mingw" then
+ hpath = os.iorunv(cygpath.program, {"--windows", line})
+
+ if opt.arch == "x86_64" then
+ local basehpath = os.iorunv(cygpath.program, {"--windows", "/mingw64/include"})
+ table.insert(result.includedirs, basehpath)
+ else
+ local basehpath = os.iorunv(cygpath.program, {"--windows", "/mingw32/include"})
+ table.insert(result.includedirs, basehpath)
+ end
+ end
+ table.insert(result.includedirs, path.directory(hpath))
+ -- remove lib and .a, .dll.a and .so to have the links
+ elseif line:endswith(".dll.a") then -- only for mingw
+ local apath = os.iorunv(cygpath.program, {"--windows", line})
+ apath = apath:trim()
+ table.insert(result.linkdirs, path.directory(apath))
+ table.insert(result.links, target.linkname(path.filename(apath), {plat = opt.plat}))
+ elseif line:endswith(".so") then
+ table.insert(result.linkdirs, path.directory(line))
+ table.insert(result.links, target.linkname(path.filename(line), {plat = opt.plat}))
+ elseif line:endswith(".a") then
+ local apath = line
+ if is_subhost("msys") and opt.plat == "mingw" then
+ apath = os.iorunv(cygpath.program, {"--windows", line})
+ apath = apath:trim()
+ end
+ table.insert(result.linkdirs, path.directory(apath))
+ table.insert(result.links, target.linkname(path.filename(apath), {plat = opt.plat}))
+ end
+ end
+ result.includedirs = table.unique(result.includedirs)
+ result.linkdirs = table.unique(result.linkdirs)
+ result.links = table.reverse_unique(result.links)
+
+ -- use pacman package version as version
+ local version = try { function() return os.iorunv(pacman.program, {"-Q", name}) end }
+ if version then
+ version = version:trim():split('%s+')[2]
+ result.version = version:split('-')[1]
+ else
+ result = nil
+ end
+ return result
+end
+
-- find package from the system directories
--
-- @param name the package name
@@ -30,17 +95,15 @@ import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkg
--
function main(name, opt)
- -- init options
- opt = opt or {}
-
-- find pacman
+ opt = opt or {}
local pacman = find_tool("pacman")
if not pacman then
return
end
-- for msys2/mingw? mingw-w64-[i686|x86_64]-xxx
- if opt.plat == "mingw" then
+ if is_subhost("msys") and opt.plat == "mingw" then
name = (opt.arch == "x86_64" and "mingw-w64-x86_64-" or "mingw-w64-i686-") .. name
end
@@ -52,41 +115,50 @@ function main(name, opt)
-- parse package files list
local linkdirs = {}
- local has_includes = false
local pkgconfig_files = {}
for _, line in ipairs(list:split('\n', {plain = true})) do
line = line:trim():split('%s+')[2]
if line:find("/pkgconfig/", 1, true) and line:endswith(".pc") then
- pkgconfig_files[path.basename(line)] = line
+ table.insert(pkgconfig_files, line)
end
if line:endswith(".so") or line:endswith(".a") or line:endswith(".lib") then
table.insert(linkdirs, path.directory(line))
- elseif line:find("/include/", 1, true) and (line:endswith(".h") or line:endswith(".hpp")) then
- has_includes = true
end
end
+ linkdirs = table.unique(linkdirs)
- -- get pkgconfig file
- local pkgconfig_file = pkgconfig_files[name]
- if not pkgconfig_file then
- for _, file in pairs(pkgconfig_files) do
- pkgconfig_file = file
- break
- end
- end
-
- -- find package
- local result = nil
- if pkgconfig_file then
+ -- we iterate over each pkgconfig file to extract the required data
+ local foundpc = false
+ local result = {includedirs = {}, linkdirs = {}, links = {}}
+ for _, pkgconfig_file in ipairs(pkgconfig_files) do
local pkgconfig_dir = path.directory(pkgconfig_file)
local pkgconfig_name = path.basename(pkgconfig_file)
- linkdirs = table.unique(linkdirs)
- includedirs = table.unique(includedirs)
- result = find_package_from_pkgconfig(pkgconfig_name, {configdirs = pkgconfig_dir, linkdirs = linkdirs})
- if not result and has_includes then
- -- header only and hidden /usr/include? we need only return empty {}
- result = {}
+ local pcresult = find_package_from_pkgconfig(pkgconfig_name, {configdirs = pkgconfig_dir, linkdirs = linkdirs})
+
+ -- the pkgconfig file has been parse successfully
+ if pcresult then
+ for _, includedir in ipairs(pcresult.includedirs) do
+ table.insert(result.includedirs, includedir)
+ end
+ for _, linkdir in ipairs(pcresult.linkdirs) do
+ table.insert(result.linkdirs, linkdir)
+ end
+ for _, link in ipairs(pcresult.links) do
+ table.insert(result.links, link)
+ end
+ -- version should be the same if a pacman package contains multiples .pc
+ result.version = pcresult.version
+ foundpc = true
end
end
+
+ if foundpc == true then
+ result.includedirs = table.unique(result.includedirs)
+ result.linkdirs = table.unique(result.linkdirs)
+ result.links = table.reverse_unique(result.links)
+ else
+ -- if there is no .pc, we parse the package content to obtain the data we want
+ result = _find_package_from_list(list, name, pacman, opt)
+ end
return result
end
diff --git a/xmake/modules/package/manager/pkgconfig/find_package.lua b/xmake/modules/package/manager/pkgconfig/find_package.lua
index a7dbf377a..ddc7efeb4 100644
--- a/xmake/modules/package/manager/pkgconfig/find_package.lua
+++ b/xmake/modules/package/manager/pkgconfig/find_package.lua
@@ -20,7 +20,6 @@
-- imports
import("lib.detect.pkgconfig")
-import("lib.detect.find_library")
import("package.manager.system.find_package", {alias = "find_package_from_system"})
-- find package from the pkg-config package manager
diff --git a/xmake/modules/package/manager/system/find_package.lua b/xmake/modules/package/manager/system/find_package.lua
index 9bb04566d..1e0d58c77 100644
--- a/xmake/modules/package/manager/system/find_package.lua
+++ b/xmake/modules/package/manager/system/find_package.lua
@@ -26,41 +26,13 @@ import("lib.detect.pkgconfig")
import("detect.sdks.find_xcode")
import("core.project.config")
--- find package from the unix-like system directories
-function _find_package_from_unixdirs(name, links, opt)
-
- -- add default search includedirs on pc host
- local includedirs = table.wrap(opt.includedirs)
- if #includedirs == 0 then
- if opt.plat == "linux" or opt.plat == "macosx" then
- table.insert(includedirs, "/usr/local/include")
- table.insert(includedirs, "/usr/include")
- table.insert(includedirs, "/opt/local/include")
- table.insert(includedirs, "/opt/include")
- end
- end
-
- -- add default search linkdirs on pc host
- local linkdirs = table.wrap(opt.linkdirs)
- if #linkdirs == 0 then
- if opt.plat == "linux" or opt.plat == "macosx" then
- table.insert(linkdirs, "/usr/local/lib")
- table.insert(linkdirs, "/usr/lib")
- table.insert(linkdirs, "/opt/local/lib")
- table.insert(linkdirs, "/opt/lib")
- if opt.plat == "linux" and opt.arch == "x86_64" then
- table.insert(linkdirs, "/usr/local/lib/x86_64-linux-gnu")
- table.insert(linkdirs, "/usr/lib/x86_64-linux-gnu")
- table.insert(linkdirs, "/usr/lib64")
- table.insert(linkdirs, "/opt/lib64")
- end
- end
- end
+-- find package
+function _find_package(name, links, linkdirs, includedirs, opt)
-- find library
local result = nil
for _, link in ipairs(links) do
- local libinfo = find_library(link, linkdirs)
+ local libinfo = find_library(link, linkdirs, {plat = opt.plat})
if libinfo then
result = result or {}
result.links = table.join(result.links or {}, libinfo.link)
@@ -91,6 +63,68 @@ function _find_package_from_unixdirs(name, links, opt)
return result
end
+-- find package from the environment variables
+-- @see https://github.com/xmake-io/xmake/issues/1776
+--
+function _find_package_from_envs(name, links, opt)
+
+ -- add default search includedirs on pc host
+ local includedirs = table.wrap(opt.includedirs)
+ if #includedirs == 0 then
+ if opt.plat == "windows" then
+ table.insert(includedirs, "$(env INCLUDE)")
+ else
+ table.insert(includedirs, "$(env CPATH)")
+ table.insert(includedirs, "$(env C_INCLUDE_PATH)")
+ table.insert(includedirs, "$(env CPLUS_INCLUDE_PATH)")
+ end
+ end
+
+ -- add default search linkdirs on pc host
+ local linkdirs = table.wrap(opt.linkdirs)
+ if #linkdirs == 0 then
+ if opt.plat == "windows" then
+ table.insert(linkdirs, "$(env LIB)")
+ else
+ table.insert(linkdirs, "$(env LIBRARY_PATH)")
+ end
+ end
+ return _find_package(name, links, linkdirs, includedirs, opt)
+end
+
+-- find package from the unix-like system directories
+function _find_package_from_unixdirs(name, links, opt)
+
+ -- add default search includedirs on pc host
+ local includedirs = table.wrap(opt.includedirs)
+ if #includedirs == 0 then
+ if opt.plat == "linux" or opt.plat == "macosx" then
+ table.insert(includedirs, "/usr/local/include")
+ table.insert(includedirs, "/usr/include")
+ table.insert(includedirs, "/opt/local/include")
+ table.insert(includedirs, "/opt/include")
+ end
+ end
+
+ -- add default search linkdirs on pc host
+ local linkdirs = table.wrap(opt.linkdirs)
+ if #linkdirs == 0 then
+ if opt.plat == "linux" or opt.plat == "macosx" then
+ table.insert(linkdirs, "/usr/local/lib")
+ table.insert(linkdirs, "/usr/lib")
+ table.insert(linkdirs, "/opt/local/lib")
+ table.insert(linkdirs, "/opt/lib")
+ if opt.plat == "linux" and opt.arch == "x86_64" then
+ table.insert(linkdirs, "/usr/local/lib/x86_64-linux-gnu")
+ table.insert(linkdirs, "/usr/lib/x86_64-linux-gnu")
+ table.insert(linkdirs, "/usr/lib64")
+ table.insert(linkdirs, "/opt/lib64")
+ end
+ end
+ end
+ return _find_package(name, links, linkdirs, includedirs, opt)
+end
+
-- find package from the xcode directories
function _find_package_from_xcodedirs(name, links, opt)
@@ -166,6 +200,7 @@ function main(name, opt)
if opt.plat ~= "windows" then
table.insert(finders, _find_package_from_unixdirs)
end
+ table.insert(finders, _find_package_from_envs)
end
if opt.plat == "macosx" or opt.plat == "iphoneos" or opt.plat == "watchos" then
table.insert(finders, _find_package_from_xcodedirs)
diff --git a/xmake/modules/package/manager/vcpkg/configurations.lua b/xmake/modules/package/manager/vcpkg/configurations.lua
new file mode 100644
index 000000000..9021edff0
--- /dev/null
+++ b/xmake/modules/package/manager/vcpkg/configurations.lua
@@ -0,0 +1,48 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file configurations.lua
+--
+
+-- get architecture for vcpkg
+function arch(arch)
+ local archs = {
+ x86_64 = "x64",
+ i386 = "x86",
+
+ -- android: armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mip64
+ -- Offers a doc: https://github.com/microsoft/vcpkg/blob/master/docs/users/android.md
+ ["armeabi-v7a"] = "arm",
+ ["arm64-v8a"] = "arm64",
+
+ -- ios: arm64 armv7 armv7s i386
+ armv7 = "arm",
+ armv7s = "arm",
+ arm64 = "arm64",
+ }
+ return archs[arch] or arch
+end
+
+-- get configurations
+function main()
+ return {
+ baseline = {description = "set the builtin baseline."},
+ features = {description = "set the features of dependency."},
+ default_features = {description = "enables or disables any defaults provided by the dependency.", default = true}
+ }
+end
+
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua
index e965ace73..e61e56c29 100644
--- a/xmake/modules/package/manager/vcpkg/find_package.lua
+++ b/xmake/modules/package/manager/vcpkg/find_package.lua
@@ -20,29 +20,51 @@
-- imports
import("lib.detect.find_file")
-import("lib.detect.find_library")
import("lib.detect.find_tool")
import("core.base.option")
import("core.project.config")
import("core.project.target")
import("detect.sdks.find_vcpkgdir")
+import("package.manager.vcpkg.configurations")
+import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
--- find package from the vcpkg package manager
---
--- @param name the package name, e.g. zlib, pcre
--- @param opt the options, e.g. {verbose = true, version = "1.12.x")
---
-function main(name, opt)
+-- we iterate over each pkgconfig file to extract the required data
+function _find_package_from_pkgconfig(pkgconfig_files, opt)
+ opt = opt or {}
+ local foundpc = false
+ local result = {includedirs = {}, linkdirs = {}, links = {}}
+ for _, pkgconfig_file in ipairs(pkgconfig_files) do
+ local pkgconfig_dir = path.join(opt.installdir, path.directory(pkgconfig_file))
+ local pkgconfig_name = path.basename(pkgconfig_file)
+ local pcresult = find_package_from_pkgconfig(pkgconfig_name, {configdirs = pkgconfig_dir, linkdirs = opt.linkdirs})
- -- attempt to find vcpkg directory
- local vcpkgdir = find_vcpkgdir()
- if not vcpkgdir then
- if option.get("diagnosis") then
- cprint("${color.warning}checkinfo: ${clear dim}vcpkg root directory not found, maybe you need set $VCPKG_ROOT!")
+ -- the pkgconfig file has been parse successfully
+ if pcresult then
+ for _, includedir in ipairs(pcresult.includedirs) do
+ table.insert(result.includedirs, includedir)
+ end
+ for _, linkdir in ipairs(pcresult.linkdirs) do
+ table.insert(result.linkdirs, linkdir)
+ end
+ for _, link in ipairs(pcresult.links) do
+ table.insert(result.links, link)
+ end
+ -- version should be the same if a pacman package contains multiples .pc
+ result.version = pcresult.version
+ foundpc = true
end
- return
end
+ if foundpc == true then
+ result.includedirs = table.unique(result.includedirs)
+ result.linkdirs = table.unique(result.linkdirs)
+ result.links = table.reverse_unique(result.links)
+ return result
+ end
+end
+
+function _find_package(vcpkgdir, name, opt)
+
-- fix name, e.g. ffmpeg[x264] as ffmpeg
-- @see https://github.com/xmake-io/xmake/issues/925
name = name:gsub("%[.-%]", "")
@@ -51,50 +73,36 @@ function main(name, opt)
local arch = opt.arch
local plat = opt.plat
local mode = opt.mode
-
- -- mapping plat
if plat == "macosx" then
plat = "osx"
end
+ arch = configurations.arch(arch)
- -- archs mapping for vcpkg
- local archs = {
- x86_64 = "x64",
- i386 = "x86",
-
- -- android: armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mip64
- -- Offers a doc: https://github.com/microsoft/vcpkg/blob/master/docs/users/android.md
- ["armeabi-v7a"] = "arm",
- ["arm64-v8a"] = "arm64",
-
- -- ios: arm64 armv7 armv7s i386
- armv7 = "arm",
- armv7s = "arm",
- arm64 = "arm64",
+ -- get the vcpkg info directories
+ local infodirs = {
+ path.join(opt.installdir, "vcpkg_installed", "vcpkg", "info"),
+ path.join(vcpkgdir, "installed", "vcpkg", "info")
}
- -- mapping arch
- arch = archs[arch] or arch
-
- -- get the vcpkg installed directory
- local installdir = path.join(vcpkgdir, "installed")
-
- -- get the vcpkg info directory
- local infodir = path.join(installdir, "vcpkg", "info")
-- find the package info file, e.g. zlib_1.2.11-3_x86-windows[-static].list
local triplet = arch .. "-" .. plat
- local pkgconfigs = opt.pkgconfigs
- if plat == "windows" and pkgconfigs and pkgconfigs.shared ~= true then
+ local configs = opt.configs or {}
+ if plat == "windows" and configs.shared ~= true then
triplet = triplet .. "-static"
- if pkgconfigs.vs_runtime and pkgconfigs.vs_runtime:startswith("MD") then
+ if configs.vs_runtime and configs.vs_runtime:startswith("MD") then
triplet = triplet .. "-md"
end
end
- local infofile = find_file(format("%s_*_%s.list", name, triplet), infodir)
+ local infofile = find_file(format("%s_*_%s.list", name, triplet), infodirs)
+ if not infofile then
+ return
+ end
+ local installdir = path.directory(path.directory(path.directory(infofile)))
-- save includedirs, linkdirs and links
local result = nil
- local info = infofile and io.readfile(infofile) or nil
+ local pkgconfig_files = {}
+ local info = io.readfile(infofile)
if info then
for _, line in ipairs(info:split('\n')) do
line = line:trim()
@@ -102,6 +110,11 @@ function main(name, opt)
line = line:lower()
end
+ -- get pkgconfig files
+ if line:find(triplet .. (mode == "debug" and "/debug" or "") .. "/lib/pkgconfig/", 1, true) and line:endswith(".pc") then
+ table.insert(pkgconfig_files, line)
+ end
+
-- get includedirs
if line:endswith("/include/") then
result = result or {}
@@ -110,14 +123,14 @@ function main(name, opt)
end
-- get linkdirs and links
- if (plat == "windows" and line:endswith(".lib")) or line:endswith(".a") then
+ if (plat == "windows" and line:endswith(".lib")) or line:endswith(".a") or line:endswith(".so") then
if line:find(triplet .. (mode == "debug" and "/debug" or "") .. "/lib/", 1, true) then
result = result or {}
result.links = result.links or {}
result.linkdirs = result.linkdirs or {}
result.libfiles = result.libfiles or {}
table.insert(result.linkdirs, path.join(installdir, path.directory(line)))
- table.insert(result.links, target.linkname(path.filename(line)))
+ table.insert(result.links, target.linkname(path.filename(line), {plat = plat}))
table.insert(result.libfiles, path.join(installdir, path.directory(line), path.filename(line)))
end
end
@@ -135,8 +148,16 @@ function main(name, opt)
end
end
+ -- find result from pkgconfig first
+ if #pkgconfig_files > 0 then
+ local pkgconfig_result = _find_package_from_pkgconfig(pkgconfig_files, {installdir = installdir, linkdirs = result and result.linkdirs})
+ if pkgconfig_result then
+ result = pkgconfig_result
+ end
+ end
+
-- save version
- if result and infofile then
+ if result then
local infoname = path.basename(infofile)
result.version = infoname:match(name .. "_(%d+%.?%d*%.?%d*.-)_" .. arch)
if not result.version then
@@ -156,3 +177,22 @@ function main(name, opt)
return result
end
+-- find package from the vcpkg package manager
+--
+-- @param name the package name, e.g. zlib, pcre
+-- @param opt the options, e.g. {verbose = true)
+--
+function main(name, opt)
+
+ -- attempt to find vcpkg directory
+ local vcpkgdir = find_vcpkgdir()
+ if not vcpkgdir then
+ if option.get("diagnosis") then
+ cprint("${color.warning}checkinfo: ${clear dim}vcpkg root directory not found, maybe you need set $VCPKG_ROOT!")
+ end
+ return
+ end
+
+ -- do find package
+ return _find_package(vcpkgdir, name, opt)
+end
diff --git a/xmake/modules/package/manager/vcpkg/install_package.lua b/xmake/modules/package/manager/vcpkg/install_package.lua
index eaf28710e..962c72f83 100644
--- a/xmake/modules/package/manager/vcpkg/install_package.lua
+++ b/xmake/modules/package/manager/vcpkg/install_package.lua
@@ -20,52 +20,67 @@
-- imports
import("core.base.option")
+import("core.base.json")
+import("core.base.semver")
import("lib.detect.find_tool")
+import("package.manager.vcpkg.configurations")
--- install package
---
--- @param name the package name, e.g. pcre2, pcre2/libpcre2-8
--- @param opt the options, e.g. {verbose = true}
---
--- @return true or false
---
-function main(name, opt)
-
- -- attempt to find vcpkg
- local vcpkg = find_tool("vcpkg")
- if not vcpkg then
- raise("vcpkg not found!")
+-- need manifest mode?
+function _need_manifest(opt)
+ local require_version = opt.require_version
+ if require_version ~= nil and require_version ~= "latest" then
+ return true
+ end
+ local configs = opt.configs
+ if configs and (configs.features or configs.default_features == false or configs.baseline) then
+ return true
end
+end
+
+-- install for classic mode
+function _install_for_classic(vcpkg, name, opt)
-- get arch, plat and mode
local arch = opt.arch
local plat = opt.plat
local mode = opt.mode
-
- -- mapping plat
if plat == "macosx" then
plat = "osx"
end
+ arch = configurations.arch(arch)
- -- archs mapping for vcpkg
- local archs = {
- x86_64 = "x64",
- i386 = "x86",
+ -- init triplet
+ local triplet = arch .. "-" .. plat
+ if opt.plat == "windows" and opt.shared ~= true then
+ triplet = triplet .. "-static"
+ if opt.vs_runtime and opt.vs_runtime:startswith("MD") then
+ triplet = triplet .. "-md"
+ end
+ end
- -- android: armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mip64
- -- Offers a doc: https://github.com/microsoft/vcpkg/blob/master/docs/users/android.md
- ["armeabi-v7a"] = "arm",
- ["arm64-v8a"] = "arm64",
+ -- init argv
+ local argv = {"install", name .. ":" .. triplet}
+ if option.get("diagnosis") then
+ table.insert(argv, "--debug")
+ end
+
+ -- install package
+ os.vrunv(vcpkg, argv)
+end
- -- ios: arm64 armv7 armv7s i386
- armv7 = "arm",
- armv7s = "arm",
- arm64 = "arm64",
- }
- -- mapping arch
- arch = archs[arch] or arch
+-- install for manifest mode
+function _install_for_manifest(vcpkg, name, opt)
+
+ -- get configs
+ local configs = opt.configs or {}
-- init triplet
+ local arch = opt.arch
+ local plat = opt.plat
+ if plat == "macosx" then
+ plat = "osx"
+ end
+ arch = configurations.arch(arch)
local triplet = arch .. "-" .. plat
if opt.plat == "windows" and opt.shared ~= true then
triplet = triplet .. "-static"
@@ -75,11 +90,83 @@ function main(name, opt)
end
-- init argv
- local argv = {"install", name .. ":" .. triplet}
+ local argv = {"--feature-flags=\"versions\"", "install", "--x-wait-for-lock", "--triplet", triplet}
if option.get("diagnosis") then
table.insert(argv, "--debug")
end
+ -- generate platform
+ local platform = plat .. " & " .. arch
+
+ -- generate dependencies
+ local require_version = opt.require_version
+ if require_version == "latest" then
+ require_version = nil
+ end
+ -- 1.2.11+13 -> 1.2.11#13
+ if require_version then
+ require_version = require_version:gsub("%+", "#")
+ end
+ local minversion = require_version
+ if minversion and minversion:startswith(">=") then
+ minversion = minversion:sub(3)
+ end
+ local dependencies = {}
+ table.insert(dependencies, {
+ name = name,
+ ["version>="] = minversion,
+ platform = platform,
+ features = configs.features,
+ ["default-features"] = configs.default_features})
+
+ -- generate overrides to use fixed version
+ local overrides
+ if require_version and semver.is_valid(require_version) then
+ overrides = {{name = name, version = require_version}}
+ end
+
+ -- generate manifest
+ local baseline = configs.baseline or "44d94c2edbd44f0c01d66c2ad95eb6982a9a61bc" -- 2021.04.30
+ local manifest = {
+ name = "stub",
+ version = "1.0",
+ dependencies = dependencies,
+ ["builtin-baseline"] = baseline,
+ overrides = overrides}
+ local installdir = assert(opt.installdir, "installdir not found!")
+ json.savefile(path.join(installdir, "vcpkg.json"), manifest)
+ if not os.isdir(installdir) then
+ os.mkdir(installdir)
+ end
+ if option.get("diagnosis") then
+ vprint(path.join(installdir, "vcpkg.json"))
+ vprint(manifest)
+ end
+
-- install package
- os.vrunv(vcpkg.program, argv)
+ os.vrunv(vcpkg, argv, {curdir = installdir})
+end
+
+-- install package
+--
+-- @param name the package name, e.g. pcre2, pcre2/libpcre2-8
+-- @param opt the options, e.g. {verbose = true}
+--
+-- @return true or false
+--
+function main(name, opt)
+
+ -- attempt to find vcpkg
+ local vcpkg = find_tool("vcpkg")
+ if not vcpkg then
+ raise("vcpkg not found!")
+ end
+
+ -- do install
+ opt = opt or {}
+ if _need_manifest(opt) then
+ _install_for_manifest(vcpkg.program, name, opt)
+ else
+ _install_for_classic(vcpkg.program, name, opt)
+ end
end
diff --git a/xmake/modules/package/manager/xmake/find_package.lua b/xmake/modules/package/manager/xmake/find_package.lua
index dab32de33..503d1beda 100644
--- a/xmake/modules/package/manager/xmake/find_package.lua
+++ b/xmake/modules/package/manager/xmake/find_package.lua
@@ -38,7 +38,11 @@ function _find_package_from_repo(name, opt)
-- find the manifest file of package, e.g. ~/.xmake/packages/z/zlib/1.1.12/ed41d5327fad3fc06fe376b4a94f62ef/manifest.txt
local packagedirs = {}
- table.insert(packagedirs, path.join(package.installdir(), name:lower():sub(1, 1), name:lower(), opt.require_version, opt.buildhash))
+ if opt.installdir then
+ table.insert(packagedirs, opt.installdir)
+ else
+ table.insert(packagedirs, path.join(package.installdir(), name:lower():sub(1, 1), name:lower(), opt.require_version, opt.buildhash))
+ end
local manifest_file = find_file("manifest.txt", packagedirs)
if not manifest_file then
return
@@ -73,39 +77,35 @@ function _find_package_from_repo(name, opt)
local links = {}
local linkdirs = {}
local libfiles = {}
- for _, linkdir in ipairs(vars.linkdirs) do
- table.insert(linkdirs, path.join(installdir, linkdir))
- end
if vars.links then
table.join2(links, vars.links)
- end
- if not vars.linkdirs or not vars.links then
+ else
+ -- we scan links automatically
local found = false
- for _, file in ipairs(os.files(path.join(installdir, "lib", "*"))) do
- if file:endswith(".lib") or file:endswith(".a") then
- found = true
- if not vars.linkdirs then
- table.insert(linkdirs, path.directory(file))
- end
- if not vars.links then
- table.insert(links, target.linkname(path.filename(file)))
+ for _, libdir in ipairs(vars.linkdirs or "lib") do
+ for _, file in ipairs(os.files(path.join(installdir, libdir, "*"))) do
+ if file:endswith(".lib") or file:endswith(".a") then
+ found = true
+ table.insert(links, target.linkname(path.filename(file), {plat = opt.plat}))
+ table.insert(libfiles, file)
end
end
- end
- if not found then
- for _, file in ipairs(os.files(path.join(installdir, "lib", "*"))) do
- if file:endswith(".so") or file:endswith(".dylib") then
- if not vars.linkdirs then
- table.insert(linkdirs, path.directory(file))
- end
- if not vars.links then
- table.insert(links, target.linkname(path.filename(file)))
+ if not found then
+ for _, file in ipairs(os.files(path.join(installdir, "lib", "*"))) do
+ if file:endswith(".so") or file:match(".+%.so%..+$") or file:endswith(".dylib") then -- maybe symlink to libxxx.so.1
+ table.insert(links, target.linkname(path.filename(file), {plat = opt.plat}))
+ table.insert(libfiles, file)
end
end
end
end
end
- if opt.plat == "windows" then
+ if #links > 0 then
+ for _, libdir in ipairs(vars.linkdirs or "lib") do
+ table.insert(linkdirs, path.join(installdir, libdir))
+ end
+ end
+ if opt.plat == "windows" or opt.plat == "mingw" then
for _, file in ipairs(os.files(path.join(installdir, "lib", "*.dll"))) do
result.shared = true
table.insert(libfiles, file)
@@ -128,7 +128,7 @@ function _find_package_from_repo(name, opt)
-- find library
for _, link in ipairs(links) do
- local libinfo = find_library(link, linkdirs)
+ local libinfo = find_library(link, linkdirs, {plat = opt.plat})
if libinfo then
if libinfo.kind == "shared" then
result.shared = true
@@ -145,7 +145,7 @@ function _find_package_from_repo(name, opt)
result.links = table.unique(result.links)
end
if result.libfiles then
- result.libfiles = table.join(result.libfiles, libfiles)
+ result.libfiles = table.unique(table.join(result.libfiles, libfiles))
end
-- inherit the other prefix variables
@@ -245,7 +245,7 @@ function _find_package_from_packagedirs(name, opt)
-- find library
local result = nil
for _, link in ipairs(packageinfo:get("links")) do
- local libinfo = find_library(link, linkdirs)
+ local libinfo = find_library(link, linkdirs, {plat = opt.plat})
if libinfo then
result = result or {}
result.links = table.join(result.links or {}, libinfo.link)
diff --git a/xmake/modules/package/manager/xmake/search_package.lua b/xmake/modules/package/manager/xmake/search_package.lua
index 5b633852c..f4a235246 100644
--- a/xmake/modules/package/manager/xmake/search_package.lua
+++ b/xmake/modules/package/manager/xmake/search_package.lua
@@ -19,6 +19,7 @@
--
-- imports
+import("core.base.semver")
import("core.package.package", {alias = "core_package"})
import("private.action.require.impl.repository")
@@ -33,6 +34,10 @@ function main(name)
if package then
local repo = package:repo()
local versions = package:versions()
+ if versions then
+ versions = table.copy(versions)
+ table.sort(versions, function (a, b) return semver.compare(a, b) > 0 end)
+ end
table.insert(results, {name = package:name(), version = versions and versions[1], description = package:get("description"), reponame = repo and repo:name()})
end
end
diff --git a/xmake/modules/package/tools/autoconf.lua b/xmake/modules/package/tools/autoconf.lua
index 209e6c68a..12b94d64f 100644
--- a/xmake/modules/package/tools/autoconf.lua
+++ b/xmake/modules/package/tools/autoconf.lua
@@ -23,13 +23,22 @@ import("core.base.option")
import("core.project.config")
import("core.tool.linker")
import("core.tool.compiler")
+import("lib.detect.find_tool")
--- translate path
-function _translate_path(package, p)
- if p and is_host("windows") and (package:is_plat("mingw") or package:is_plat("msys") or package:is_plat("cygwin")) then
- p = p:gsub("\\", "/")
+-- translate paths
+function _translate_paths(package, paths)
+ if paths and is_host("windows") and (package:is_plat("mingw") or package:is_plat("msys") or package:is_plat("cygwin")) then
+ if type(paths) == "string" then
+ return (paths:gsub("\\", "/"))
+ elseif type(paths) == "table" then
+ local result = {}
+ for _, p in ipairs(paths) do
+ table.insert(result, (p:gsub("\\", "/")))
+ end
+ return result
+ end
end
- return p
+ return paths
end
-- translate windows bin path
@@ -56,7 +65,7 @@ function _get_configs(package, configs)
-- add prefix
local configs = configs or {}
- table.insert(configs, "--prefix=" .. _translate_path(package, package:installdir()))
+ table.insert(configs, "--prefix=" .. _translate_paths(package, package:installdir()))
-- add host for cross-complation
if not configs.host and not package:is_plat(os.subhost()) then
@@ -108,10 +117,45 @@ function _get_configs(package, configs)
return configs
end
+-- get cflags from package deps
+function _get_cflags_from_packagedeps(package, opt)
+ local result = {}
+ for _, depname in ipairs(opt.packagedeps) do
+ local dep = package:dep(depname)
+ if dep then
+ local fetchinfo = dep:fetch({external = false})
+ if fetchinfo then
+ table.join2(result, _map_compflags(package, "cxx", "define", fetchinfo.defines))
+ table.join2(result, _translate_paths(package, _map_compflags(package, "cxx", "includedir", fetchinfo.includedirs)))
+ table.join2(result, _translate_paths(package, _map_compflags(package, "cxx", "sysincludedir", fetchinfo.sysincludedirs)))
+ end
+ end
+ end
+ return result
+end
+
+-- get ldflags from package deps
+function _get_ldflags_from_packagedeps(package, opt)
+ local result = {}
+ for _, depname in ipairs(opt.packagedeps) do
+ local dep = package:dep(depname)
+ if dep then
+ local fetchinfo = dep:fetch({external = false})
+ if fetchinfo then
+ table.join2(result, _translate_paths(package, _map_linkflags(package, "binary", {"cxx"}, "linkdir", fetchinfo.linkdirs)))
+ table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "link", fetchinfo.links))
+ table.join2(result, _translate_paths(package, _map_linkflags(package, "binary", {"cxx"}, "syslink", fetchinfo.syslinks)))
+ end
+ end
+ end
+ return result
+end
+
-- get the build environments
function buildenvs(package, opt)
opt = opt or {}
local envs = {}
+ local cppflags = {}
if package:is_plat(os.subhost()) then
local cflags = table.join(table.wrap(package:config("cxflags")), package:config("cflags"))
local cxxflags = table.join(table.wrap(package:config("cxflags")), package:config("cxxflags"))
@@ -127,10 +171,16 @@ function buildenvs(package, opt)
table.join2(cflags, opt.cxflags)
table.join2(cxxflags, opt.cxxflags)
table.join2(cxxflags, opt.cxflags)
+ table.join2(cppflags, opt.cppflags) -- @see https://github.com/xmake-io/xmake/issues/1688
table.join2(asflags, opt.asflags)
table.join2(ldflags, opt.ldflags)
+ table.join2(cflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(cxxflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(cppflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(ldflags, _get_ldflags_from_packagedeps(package, opt))
envs.CFLAGS = table.concat(cflags, ' ')
envs.CXXFLAGS = table.concat(cxxflags, ' ')
+ envs.CPPFLAGS = table.concat(cppflags, ' ')
envs.ASFLAGS = table.concat(asflags, ' ')
envs.LDFLAGS = table.concat(ldflags, ' ')
else
@@ -150,9 +200,14 @@ function buildenvs(package, opt)
table.join2(cflags, opt.cxflags)
table.join2(cxxflags, opt.cxxflags)
table.join2(cxxflags, opt.cxflags)
+ table.join2(cppflags, opt.cppflags) -- @see https://github.com/xmake-io/xmake/issues/1688
table.join2(asflags, opt.asflags)
table.join2(ldflags, opt.ldflags)
table.join2(shflags, opt.shflags)
+ table.join2(cflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(cxxflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(cppflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(ldflags, _get_ldflags_from_packagedeps(package, opt))
table.join2(cflags, _map_compflags(package, "c", "define", defines))
table.join2(cflags, _map_compflags(package, "c", "includedir", includedirs))
table.join2(cflags, _map_compflags(package, "c", "sysincludedir", sysincludedirs))
@@ -177,6 +232,7 @@ function buildenvs(package, opt)
envs.RANLIB = package:build_getenv("ranlib")
envs.CFLAGS = table.concat(cflags, ' ')
envs.CXXFLAGS = table.concat(cxxflags, ' ')
+ envs.CPPFLAGS = table.concat(cppflags, ' ')
envs.ASFLAGS = table.concat(asflags, ' ')
envs.ARFLAGS = table.concat(arflags, ' ')
envs.LDFLAGS = table.concat(ldflags, ' ')
@@ -291,25 +347,75 @@ function configure(package, configs, opt)
os.vrunv("sh", argv, {envs = envs})
end
--- install package
-function install(package, configs, opt)
+-- do make
+function make(package, argv, opt)
+ opt = opt or {}
+ local program
+ if package:is_plat("mingw") and is_subhost("windows") then
+ local mingw = assert(package:build_getenv("mingw") or package:build_getenv("sdk"), "mingw not found!")
+ program = path.join(mingw, "bin", "mingw32-make.exe")
+ else
+ local tool = find_tool("make")
+ if tool then
+ program = tool.program
+ end
+ end
+ assert(program, "make not found!")
+ os.vrunv(program, argv)
+end
+
+-- build package
+function build(package, configs, opt)
-- do configure
configure(package, configs, opt)
-- do make and install
opt = opt or {}
- local njob = opt.jobs or option.get("jobs") or tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2))
+ local njob = opt.jobs or option.get("jobs") or tostring(os.default_njob())
local argv = {"-j" .. njob}
if option.get("verbose") then
table.insert(argv, "V=1")
end
- if is_host("bsd") then
- os.vrunv("gmake", argv)
- os.vrun("gmake install")
- else
- os.vrunv("make", argv)
- os.vrun("make install")
+ if opt.makeconfigs then
+ for name, value in pairs(opt.makeconfigs) do
+ value = tostring(value):trim()
+ if value ~= "" then
+ if type(name) == "number" then
+ table.insert(argv, value)
+ else
+ table.insert(argv, name .. "=" .. value)
+ end
+ end
+ end
+ end
+ make(package, argv, opt)
+end
+
+-- install package
+function install(package, configs, opt)
+
+ -- do build
+ opt = opt or {}
+ build(package, configs, opt)
+
+ -- do install
+ local argv = {"install"}
+ if option.get("verbose") then
+ table.insert(argv, "V=1")
+ end
+ if opt.makeconfigs then
+ for name, value in pairs(opt.makeconfigs) do
+ value = tostring(value):trim()
+ if value ~= "" then
+ if type(name) == "number" then
+ table.insert(argv, value)
+ else
+ table.insert(argv, name .. "=" .. value)
+ end
+ end
+ end
end
+ make(package, argv, opt)
end
diff --git a/xmake/modules/package/tools/cmake.lua b/xmake/modules/package/tools/cmake.lua
index 3e48fee40..f49cedf0b 100644
--- a/xmake/modules/package/tools/cmake.lua
+++ b/xmake/modules/package/tools/cmake.lua
@@ -30,7 +30,7 @@ import("package.tools.ninja")
-- get the number of parallel jobs
function _get_parallel_njobs(opt)
- return opt.jobs or option.get("jobs") or tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2))
+ return opt.jobs or option.get("jobs") or tostring(os.default_njob())
end
-- translate paths
@@ -272,10 +272,13 @@ function _get_configs_for_windows(package, configs, opt)
table.insert(configs, "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL")
end
if vs_runtime then
- table.insert(configs, '-DCMAKE_CXX_FLAGS_DEBUG="/' .. vs_runtime .. '"')
- table.insert(configs, '-DCMAKE_CXX_FLAGS_RELEASE="/' .. vs_runtime .. '"')
- table.insert(configs, '-DCMAKE_C_FLAGS_DEBUG="/' .. vs_runtime .. '"')
- table.insert(configs, '-DCMAKE_C_FLAGS_RELEASE="/' .. vs_runtime .. '"')
+ -- CMake default MSVC flags as of 3.21.2
+ local default_debug_flags = "/Zi /Ob0 /Od /RTC1"
+ local default_release_flags = "/O2 /Ob2 /DNDEBUG"
+ table.insert(configs, '-DCMAKE_CXX_FLAGS_DEBUG=/' .. vs_runtime .. ' ' .. default_debug_flags)
+ table.insert(configs, '-DCMAKE_CXX_FLAGS_RELEASE=/' .. vs_runtime .. ' ' .. default_release_flags)
+ table.insert(configs, '-DCMAKE_C_FLAGS_DEBUG=/' .. vs_runtime .. ' ' .. default_debug_flags)
+ table.insert(configs, '-DCMAKE_C_FLAGS_RELEASE=/' .. vs_runtime .. ' ' .. default_release_flags)
end
_get_configs_for_generic(package, configs, opt)
end
@@ -296,6 +299,12 @@ function _get_configs_for_android(package, configs, opt)
if ndk_cxxstl then
table.insert(configs, "-DANDROID_STL=" .. ndk_cxxstl)
end
+ if is_host("windows") then
+ local make = path.join(ndk, "prebuilt", "windows-x86_64", "bin", "make.exe")
+ if os.isfile(make) then
+ table.insert(configs, "-DCMAKE_MAKE_PROGRAM=" .. make)
+ end
+ end
end
_get_configs_for_generic(package, configs, opt)
end
@@ -363,6 +372,16 @@ function _get_configs_for_mingw(package, configs, opt)
envs.CMAKE_OSX_SYSROOT = ""
-- Avoid cmake to add the flags -search_paths_first and -headerpad_max_install_names on macOS
envs.HAVE_FLAG_SEARCH_PATHS_FIRST = "0"
+ -- CMAKE_MAKE_PROGRAM may be required for some CMakeLists.txt (libcurl)
+ if is_subhost("windows") then
+ local mingw = assert(package:build_getenv("mingw") or package:build_getenv("sdk"), "mingw not found!")
+ envs.CMAKE_MAKE_PROGRAM = path.join(mingw, "bin", "mingw32-make.exe")
+ end
+
+ if opt.cmake_generator == "Ninja" then
+ envs.CMAKE_MAKE_PROGRAM = "ninja"
+ end
+
for k, v in pairs(envs) do
table.insert(configs, "-D" .. k .. "=" .. v)
end
@@ -535,8 +554,12 @@ end
-- do build for make
function _build_for_make(package, configs, opt)
+ local argv = {}
+ if opt.target then
+ table.insert(argv, opt.target)
+ end
local jobs = _get_parallel_njobs(opt)
- local argv = {"-j" .. jobs}
+ table.insert(argv, "-j" .. jobs)
if option.get("verbose") then
table.insert(argv, "VERBOSE=1")
end
@@ -546,6 +569,16 @@ function _build_for_make(package, configs, opt)
local mingw = assert(package:build_getenv("mingw") or package:build_getenv("sdk"), "mingw not found!")
local mingw_make = path.join(mingw, "bin", "mingw32-make.exe")
os.vrunv(mingw_make, argv)
+ elseif package:is_plat("android") and is_host("windows") then
+ local make
+ local ndk = get_config("ndk")
+ if ndk then
+ make = path.join(ndk, "prebuilt", "windows-x86_64", "bin", "make.exe")
+ end
+ if not make or not os.isfile(make) then
+ make = "make"
+ end
+ os.vrunv(make, argv)
else
os.vrunv("make", argv)
end
@@ -602,6 +635,17 @@ function _install_for_make(package, configs, opt)
local mingw_make = path.join(mingw, "bin", "mingw32-make.exe")
os.vrunv(mingw_make, argv)
os.vrunv(mingw_make, {"install"})
+ elseif package:is_plat("android") and is_host("windows") then
+ local make
+ local ndk = get_config("ndk")
+ if ndk then
+ make = path.join(ndk, "prebuilt", "windows-x86_64", "bin", "make.exe")
+ end
+ if not make or not os.isfile(make) then
+ make = "make"
+ end
+ os.vrunv(make, argv)
+ os.vrunv(make, {"install"})
else
os.vrunv("make", argv)
os.vrunv("make", {"install"})
@@ -629,7 +673,7 @@ function build(package, configs, opt)
opt = opt or {}
-- enter build directory
- local buildir = opt.buildir or "build_" .. hash.uuid4():split('%-')[1]
+ local buildir = opt.buildir or package:buildir()
os.mkdir(path.join(buildir, "install"))
local oldir = os.cd(buildir)
@@ -688,7 +732,7 @@ function install(package, configs, opt)
opt = opt or {}
-- enter build directory
- local buildir = opt.buildir or "build_" .. hash.uuid4():split('%-')[1]
+ local buildir = opt.buildir or package:buildir()
os.mkdir(path.join(buildir, "install"))
local oldir = os.cd(buildir)
@@ -733,4 +777,3 @@ function install(package, configs, opt)
end
os.cd(oldir)
end
-
diff --git a/xmake/modules/package/tools/make.lua b/xmake/modules/package/tools/make.lua
index b236b9da6..27e73b412 100644
--- a/xmake/modules/package/tools/make.lua
+++ b/xmake/modules/package/tools/make.lua
@@ -21,6 +21,15 @@
-- imports
import("core.base.option")
import("core.project.config")
+import("lib.detect.find_tool")
+
+-- translate bin path
+function _translate_bin_path(bin_path)
+ if is_host("windows") and bin_path then
+ return bin_path:gsub("\\", "/") .. ".exe"
+ end
+ return bin_path
+end
-- get the build environments
function buildenvs(package)
@@ -43,13 +52,14 @@ function buildenvs(package)
else
local cflags = table.join(table.wrap(package:build_getenv("cxflags")), package:build_getenv("cflags"))
local cxxflags = table.join(table.wrap(package:build_getenv("cxflags")), package:build_getenv("cxxflags"))
- envs.CC = package:build_getenv("cc")
- envs.AS = package:build_getenv("as")
- envs.AR = package:build_getenv("ar")
- envs.LD = package:build_getenv("ld")
- envs.LDSHARED = package:build_getenv("sh")
- envs.CPP = package:build_getenv("cpp")
- envs.RANLIB = package:build_getenv("ranlib")
+ envs.CC = _translate_bin_path(package:build_getenv("cc"))
+ envs.CXX = _translate_bin_path(package:build_getenv("cxx"))
+ envs.AS = _translate_bin_path(package:build_getenv("as"))
+ envs.AR = _translate_bin_path(package:build_getenv("ar"))
+ envs.LD = _translate_bin_path(package:build_getenv("ld"))
+ envs.LDSHARED = _translate_bin_path(package:build_getenv("sh"))
+ envs.CPP = _translate_bin_path(package:build_getenv("cpp"))
+ envs.RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
envs.CFLAGS = table.concat(cflags, ' ')
envs.CXXFLAGS = table.concat(cxxflags, ' ')
envs.ASFLAGS = table.concat(table.wrap(package:build_getenv("asflags")), ' ')
@@ -75,9 +85,32 @@ function buildenvs(package)
end
envs.ACLOCAL_PATH = path.joinenv(ACLOCAL_PATH)
envs.PKG_CONFIG_PATH = path.joinenv(PKG_CONFIG_PATH)
+ -- some Makefile use ComSpec to detect Windows (e.g. Makefiles generated by Premake) and require this env
+ if is_subhost("windows") then
+ envs.ComSpec = os.getenv("ComSpec")
+ end
+
return envs
end
+-- do make
+function make(package, argv, opt)
+ opt = opt or {}
+ local program
+ local runenvs = opt.envs or buildenvs(package)
+ if package:is_plat("mingw") and is_subhost("windows") then
+ local mingw = assert(package:build_getenv("mingw") or package:build_getenv("sdk"), "mingw not found!")
+ program = path.join(mingw, "bin", "mingw32-make.exe")
+ else
+ local tool = find_tool("make", {envs = runenvs})
+ if tool then
+ program = tool.program
+ end
+ end
+ assert(program, "make not found!")
+ os.vrunv(program, argv, {envs = runenvs, curdir = opt.curdir})
+end
+
-- build package
function build(package, configs, opt)
@@ -85,7 +118,7 @@ function build(package, configs, opt)
opt = opt or {}
-- pass configurations
- local njob = opt.jobs or option.get("jobs") or tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2))
+ local njob = opt.jobs or option.get("jobs") or tostring(os.default_njob())
local argv = {"-j" .. njob}
if option.get("verbose") then
table.insert(argv, "VERBOSE=1")
@@ -102,11 +135,7 @@ function build(package, configs, opt)
end
-- do build
- if is_host("bsd") then
- os.vrunv("gmake", argv, {envs = opt.envs or buildenvs(package)})
- else
- os.vrunv("make", argv, {envs = opt.envs or buildenvs(package)})
- end
+ make(package, argv, opt)
end
-- install package
@@ -121,9 +150,5 @@ function install(package, configs, opt)
if option.get("verbose") then
table.insert(argv, "VERBOSE=1")
end
- if is_host("bsd") then
- os.vrunv("gmake", argv, {envs = opt.envs or buildenvs(package)})
- else
- os.vrunv("make", argv, {envs = opt.envs or buildenvs(package)})
- end
+ make(package, argv, opt)
end
diff --git a/xmake/modules/package/tools/meson.lua b/xmake/modules/package/tools/meson.lua
index 6361f2a0e..0ee1839b6 100644
--- a/xmake/modules/package/tools/meson.lua
+++ b/xmake/modules/package/tools/meson.lua
@@ -22,18 +22,31 @@
import("core.base.option")
import("core.project.config")
import("core.tool.toolchain")
+import("core.tool.linker")
+import("core.tool.compiler")
import("package.tools.ninja")
+import("lib.detect.find_tool")
-- get build directory
-function _get_buildir(opt)
+function _get_buildir(package, opt)
if opt and opt.buildir then
return opt.buildir
else
- _g.buildir = _g.buildir or ("build_" .. hash.uuid4():split('%-')[1])
+ _g.buildir = _g.buildir or package:buildir()
return _g.buildir
end
end
+-- map compiler flags
+function _map_compflags(package, langkind, name, values)
+ return compiler.map_flags(langkind, name, values, {target = package})
+end
+
+-- map linker flags
+function _map_linkflags(package, targetkind, sourcekinds, name, values)
+ return linker.map_flags(targetkind, sourcekinds, name, values, {target = package})
+end
+
-- get configs
function _get_configs(package, configs, opt)
@@ -56,7 +69,7 @@ function _get_configs(package, configs, opt)
end
-- add build directory
- table.insert(configs, _get_buildir(opt))
+ table.insert(configs, _get_buildir(package, opt))
return configs
end
@@ -79,21 +92,91 @@ function _fix_libname_on_windows(package)
end
end
+-- get cflags from package deps
+function _get_cflags_from_packagedeps(package, opt)
+ local result = {}
+ for _, depname in ipairs(opt.packagedeps) do
+ local dep = package:dep(depname)
+ if dep then
+ local fetchinfo = dep:fetch({external = false})
+ if fetchinfo then
+ table.join2(result, _map_compflags(package, "cxx", "define", fetchinfo.defines))
+ table.join2(result, _map_compflags(package, "cxx", "includedir", fetchinfo.includedirs))
+ table.join2(result, _map_compflags(package, "cxx", "sysincludedir", fetchinfo.sysincludedirs))
+ end
+ end
+ end
+ return result
+end
+
+-- get ldflags from package deps
+function _get_ldflags_from_packagedeps(package, opt)
+ local result = {}
+ for _, depname in ipairs(opt.packagedeps) do
+ local dep = package:dep(depname)
+ if dep then
+ local fetchinfo = dep:fetch({external = false})
+ if fetchinfo then
+ table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "linkdir", fetchinfo.linkdirs))
+ table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "link", fetchinfo.links))
+ table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "syslink", fetchinfo.syslinks))
+ end
+ end
+ end
+ return result
+end
+
-- get the build environments
-function buildenvs(package)
+function buildenvs(package, opt)
local envs = {}
+ opt = opt or {}
if package:is_plat(os.host()) then
local cflags = table.join(table.wrap(package:config("cxflags")), package:config("cflags"))
local cxxflags = table.join(table.wrap(package:config("cxflags")), package:config("cxxflags"))
+ local asflags = table.wrap(package:config("asflags"))
+ local ldflags = table.wrap(package:config("ldflags"))
+ local shflags = table.wrap(package:config("shflags"))
+ table.join2(cflags, opt.cflags)
+ table.join2(cflags, opt.cxflags)
+ table.join2(cxxflags, opt.cxxflags)
+ table.join2(cxxflags, opt.cxflags)
+ table.join2(asflags, opt.asflags)
+ table.join2(ldflags, opt.ldflags)
+ table.join2(shflags, opt.shflags)
+ table.join2(cflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(cxxflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(ldflags, _get_ldflags_from_packagedeps(package, opt))
+ table.join2(shflags, _get_ldflags_from_packagedeps(package, opt))
envs.CFLAGS = table.concat(cflags, ' ')
envs.CXXFLAGS = table.concat(cxxflags, ' ')
- envs.ASFLAGS = table.concat(table.wrap(package:config("asflags")), ' ')
+ envs.ASFLAGS = table.concat(asflags, ' ')
+ envs.LDFLAGS = table.concat(ldflags, ' ')
+ envs.SHFLAGS = table.concat(shflags, ' ')
if package:is_plat("windows") then
envs = os.joinenvs(envs, _get_msvc_runenvs(package))
+ local pkgconf = find_tool("pkgconf")
+ if pkgconf then
+ envs.PKG_CONFIG = pkgconf.program
+ end
end
else
local cflags = table.join(table.wrap(package:build_getenv("cxflags")), package:build_getenv("cflags"))
local cxxflags = table.join(table.wrap(package:build_getenv("cxflags")), package:build_getenv("cxxflags"))
+ local asflags = table.wrap(package:build_getenv("asflags"))
+ local arflags = table.wrap(package:build_getenv("arflags"))
+ local ldflags = table.wrap(package:build_getenv("ldflags"))
+ local shflags = table.wrap(package:build_getenv("shflags"))
+ table.join2(cflags, opt.cflags)
+ table.join2(cflags, opt.cxflags)
+ table.join2(cxxflags, opt.cxxflags)
+ table.join2(cxxflags, opt.cxflags)
+ table.join2(asflags, opt.asflags)
+ table.join2(ldflags, opt.ldflags)
+ table.join2(shflags, opt.shflags)
+ table.join2(cflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(cxxflags, _get_cflags_from_packagedeps(package, opt))
+ table.join2(ldflags, _get_ldflags_from_packagedeps(package, opt))
+ table.join2(shflags, _get_ldflags_from_packagedeps(package, opt))
envs.CC = package:build_getenv("cc")
envs.AS = package:build_getenv("as")
envs.AR = package:build_getenv("ar")
@@ -103,10 +186,10 @@ function buildenvs(package)
envs.RANLIB = package:build_getenv("ranlib")
envs.CFLAGS = table.concat(cflags, ' ')
envs.CXXFLAGS = table.concat(cxxflags, ' ')
- envs.ASFLAGS = table.concat(table.wrap(package:build_getenv("asflags")), ' ')
- envs.ARFLAGS = table.concat(table.wrap(package:build_getenv("arflags")), ' ')
- envs.LDFLAGS = table.concat(table.wrap(package:build_getenv("ldflags")), ' ')
- envs.SHFLAGS = table.concat(table.wrap(package:build_getenv("shflags")), ' ')
+ envs.ASFLAGS = table.concat(asflags, ' ')
+ envs.ARFLAGS = table.concat(arflags, ' ')
+ envs.LDFLAGS = table.concat(ldflags, ' ')
+ envs.SHFLAGS = table.concat(shflags, ' ')
end
local ACLOCAL_PATH = {}
local PKG_CONFIG_PATH = {}
@@ -149,7 +232,7 @@ function generate(package, configs, opt)
end
-- do configure
- os.vrunv("meson", argv, {envs = opt.envs or buildenvs(package)})
+ os.vrunv("meson", argv, {envs = opt.envs or buildenvs(package, opt)})
end
-- build package
@@ -160,7 +243,7 @@ function build(package, configs, opt)
generate(package, configs, opt)
-- do build
- local buildir = _get_buildir(opt)
+ local buildir = _get_buildir(package, opt)
ninja.build(package, {}, {buildir = buildir, envs = opt.envs or buildenvs(package, opt)})
end
@@ -172,7 +255,7 @@ function install(package, configs, opt)
generate(package, configs, opt)
-- do build and install
- local buildir = _get_buildir(opt)
+ local buildir = _get_buildir(package, opt)
ninja.install(package, {}, {buildir = buildir, envs = opt.envs or buildenvs(package, opt)})
-- fix static libname on windows
diff --git a/xmake/modules/package/tools/ninja.lua b/xmake/modules/package/tools/ninja.lua
index e1feccc14..0d3ad9708 100644
--- a/xmake/modules/package/tools/ninja.lua
+++ b/xmake/modules/package/tools/ninja.lua
@@ -26,9 +26,14 @@ import("lib.detect.find_tool")
function build(package, configs, opt)
opt = opt or {}
local buildir = opt.buildir or os.curdir()
- local njob = opt.jobs or option.get("jobs") or tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2))
+ local njob = opt.jobs or option.get("jobs") or tostring(os.default_njob())
local ninja = assert(find_tool("ninja"), "ninja not found!")
- local argv = {"-C", buildir}
+ local argv = {}
+ if opt.target then
+ table.insert(argv, opt.target)
+ end
+ table.insert(argv, "-C")
+ table.insert(argv, buildir)
if option.get("verbose") then
table.insert(argv, "-v")
end
@@ -44,7 +49,7 @@ end
function install(package, configs, opt)
opt = opt or {}
local buildir = opt.buildir or os.curdir()
- local njob = tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2))
+ local njob = tostring(os.default_njob())
local ninja = assert(find_tool("ninja"), "ninja not found!")
local argv = {"install", "-C", buildir}
if option.get("verbose") then
diff --git a/xmake/modules/package/tools/scons.lua b/xmake/modules/package/tools/scons.lua
index 386645bba..0c197933f 100644
--- a/xmake/modules/package/tools/scons.lua
+++ b/xmake/modules/package/tools/scons.lua
@@ -86,7 +86,7 @@ end
function build(package, configs, opt)
opt = opt or {}
local buildir = opt.buildir or os.curdir()
- local njob = opt.jobs or option.get("jobs") or tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2))
+ local njob = opt.jobs or option.get("jobs") or tostring(os.default_njob())
local scons = assert(find_tool("scons"), "scons not found!")
local argv = {"-C", buildir, "-j", njob}
configs = _get_configs(package, configs)
diff --git a/xmake/modules/package/tools/xmake.lua b/xmake/modules/package/tools/xmake.lua
index 0c7d9c294..9bfcffaff 100644
--- a/xmake/modules/package/tools/xmake.lua
+++ b/xmake/modules/package/tools/xmake.lua
@@ -59,13 +59,28 @@ function _get_configs(package, configs)
table.insert(configs, "--cross=" .. cross)
end
local bindir = _get_config_from_toolchains(package, "bindir") or get_config("bin")
- if cross then
+ if bindir then
table.insert(configs, "--bin=" .. bindir)
end
local sdkdir = _get_config_from_toolchains(package, "sdkdir") or get_config("sdk")
- if cross then
+ if sdkdir then
table.insert(configs, "--sdk=" .. sdkdir)
end
+ -- we can only modify toolchain for cross-compilation
+ --
+ -- e.g. xrepo install -p cross --toolchain=muslcc meson,
+ -- we cannot pass muslcc toolchain to it's deps(zlib, ..), because meson is always host binary and zlib is host library.
+ local toolchain_name = get_config("toolchain")
+ if toolchain_name then
+ table.insert(configs, "--toolchain=" .. toolchain_name)
+ end
+ local names = {"ld", "sh", "ar", "cc", "cxx"}
+ for _, name in ipairs(names) do
+ local value = get_config(name)
+ if value ~= nil then
+ table.insert(configs, "--" .. name .. "=" .. tostring(value))
+ end
+ end
else
local names = {"ndk", "ndk_sdkver", "vs", "mingw", "ld", "sh", "ar", "cc", "cxx", "mm", "mxx"}
for _, name in ipairs(names) do
diff --git a/xmake/modules/private/action/build/object.lua b/xmake/modules/private/action/build/object.lua
index 50397cda4..e07ab76b7 100644
--- a/xmake/modules/private/action/build/object.lua
+++ b/xmake/modules/private/action/build/object.lua
@@ -25,7 +25,7 @@ import("core.tool.compiler")
import("core.project.depend")
import("private.tools.ccache")
import("private.async.runjobs")
-import("private.utils.progress")
+import("utils.progress")
-- do build file
function _do_build_file(target, sourcefile, opt)
@@ -85,7 +85,7 @@ function _do_build_file(target, sourcefile, opt)
end
-- build object
-function _build_object(target, sourcefile, opt)
+function build_object(target, sourcefile, opt)
local script = target:script("build_file", _do_build_file)
if script then
script(target, sourcefile, opt)
@@ -99,7 +99,7 @@ function build(target, sourcebatch, opt)
opt.objectfile = sourcebatch.objectfiles[i]
opt.dependfile = sourcebatch.dependfiles[i]
opt.sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile)
- _build_object(target, sourcefile, opt)
+ build_object(target, sourcefile, opt)
end
end
@@ -113,7 +113,7 @@ function main(target, batchjobs, sourcebatch, opt)
local sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile)
batchjobs:addjob(sourcefile, function (index, total)
local build_opt = table.join({objectfile = objectfile, dependfile = dependfile, sourcekind = sourcekind, progress = (index * 100) / total}, opt)
- _build_object(target, sourcefile, build_opt)
+ build_object(target, sourcefile, build_opt)
end, {rootjob = rootjob})
end
end
diff --git a/xmake/modules/private/action/require/impl/actions/download.lua b/xmake/modules/private/action/require/impl/actions/download.lua
index bee421052..f2c8eeba7 100644
--- a/xmake/modules/private/action/require/impl/actions/download.lua
+++ b/xmake/modules/private/action/require/impl/actions/download.lua
@@ -70,13 +70,13 @@ function _checkout(package, url, sourcedir, url_alias)
if package:branch() then
-- only shadow clone this branch
- git.clone(proxy.mirror(url) or url, {depth = 1, recursive = true, longpaths = longpaths, branch = package:branch(), outputdir = packagedir})
+ git.clone(url, {depth = 1, recursive = true, longpaths = longpaths, branch = package:branch(), outputdir = packagedir})
-- download package from revision or tag?
else
-- clone whole history and tags
- git.clone(proxy.mirror(url) or url, {longpaths = longpaths, outputdir = packagedir})
+ git.clone(url, {longpaths = longpaths, outputdir = packagedir})
-- attempt to checkout the given version
local revision = package:revision(url_alias) or package:tag() or package:version_str()
@@ -139,7 +139,7 @@ function _download(package, url, sourcedir, url_alias, url_excludes)
-- we can use local package from the search directories directly if network is too slow
os.cp(localfile, packagefile)
else
- http.download(proxy.mirror(url) or url, packagefile)
+ http.download(url, packagefile)
end
end
@@ -151,15 +151,20 @@ function _download(package, url, sourcedir, url_alias, url_excludes)
-- extract package file
os.rm(sourcedir .. ".tmp")
+ local extension = archive.extension(packagefile)
if archive.extract(packagefile, sourcedir .. ".tmp", {excludes = url_excludes}) then
-- move to source directory
os.rm(sourcedir)
os.mv(sourcedir .. ".tmp", sourcedir)
- else
+ elseif extension and extension ~= "" then
-- create an empty source directory if do not extract package file
os.tryrm(sourcedir)
os.mkdir(sourcedir)
- raise("cannot extract %s", packagefile)
+ raise("cannot extract %s, maybe missing extractor or invalid package file!", packagefile)
+ else
+ -- if it is not archive file, we need only create empty source file and use package:originfile()
+ os.tryrm(sourcedir)
+ os.mkdir(sourcedir)
end
-- save original file path
@@ -224,7 +229,13 @@ function main(package)
-- filter url
url = filter.handle(url, package)
+ -- use proxy url?
+ if not os.isfile(url) then
+ url = proxy.mirror(url) or url
+ end
+
-- download url
+ local allerrors = {}
ok = try
{
function ()
@@ -243,8 +254,12 @@ function main(package)
function (errors)
-- show or save the last errors
- if errors and (option.get("verbose") or option.get("diagnosis")) then
- cprint("${dim color.error}error: ${clear}%s", errors)
+ if errors then
+ if (option.get("verbose") or option.get("diagnosis")) then
+ cprint("${dim color.error}error: ${clear}%s", errors)
+ else
+ table.insert(allerrors, errors)
+ end
end
-- trace
@@ -270,7 +285,11 @@ function main(package)
cprint(" ${bright}- %s", table.concat(searchnames:to_array(), ", "))
cprint("and we can run `xmake g --pkg_searchdirs=/xxx` to set the search directories.")
end
- raise("download failed!")
+ if #allerrors then
+ raise(table.concat(allerrors, "\n"))
+ else
+ raise("download failed!")
+ end
end
end
}
diff --git a/xmake/modules/private/action/require/impl/actions/download_resources.lua b/xmake/modules/private/action/require/impl/actions/download_resources.lua
index fa115c04a..c6af29151 100644
--- a/xmake/modules/private/action/require/impl/actions/download_resources.lua
+++ b/xmake/modules/private/action/require/impl/actions/download_resources.lua
@@ -32,6 +32,7 @@ import("utils.archive")
function _checkout(package, resource_name, resource_url, resource_revision)
-- trace
+ resource_url = proxy.mirror(resource_url) or resource_url
vprint("cloning resource(%s: %s) to %s-%s ..", resource_name, resource_revision, package:name(), package:version_str())
-- get the resource directory
@@ -62,7 +63,7 @@ function _checkout(package, resource_name, resource_url, resource_revision)
local longpaths = package:policy("platform.longpaths")
-- clone whole history and tags
- git.clone(proxy.mirror(resource_url) or resource_url, {longpaths = longpaths, outputdir = resourcedir})
+ git.clone(resource_url, {longpaths = longpaths, outputdir = resourcedir})
-- attempt to checkout the given version
git.checkout(resource_revision, {repodir = resourcedir})
@@ -77,6 +78,7 @@ end
function _download(package, resource_name, resource_url, resource_hash)
-- trace
+ resource_url = proxy.mirror(resource_url) or resource_url
vprint("downloading resource(%s: %s) to %s-%s ..", resource_name, resource_url, package:name(), package:version_str())
-- get the resource file
@@ -103,7 +105,7 @@ function _download(package, resource_name, resource_url, resource_hash)
-- we can use local resource from the search directories directly if network is too slow
os.cp(localfile, resource_file)
elseif resource_url:find(string.ipattern("https-://")) or resource_url:find(string.ipattern("ftps-://")) then
- http.download(proxy.mirror(resource_url) or resource_url, resource_file)
+ http.download(resource_url, resource_file)
else
raise("invalid resource url(%s)", resource_url)
end
diff --git a/xmake/modules/private/action/require/impl/actions/install.lua b/xmake/modules/private/action/require/impl/actions/install.lua
index 81f93681e..cbe836ed2 100644
--- a/xmake/modules/private/action/require/impl/actions/install.lua
+++ b/xmake/modules/private/action/require/impl/actions/install.lua
@@ -55,8 +55,11 @@ function _patch_pkgconfig(package)
-- get libs
local libs = ""
+ local installdir = package:installdir()
for _, linkdir in ipairs(fetchinfo.linkdirs) do
- libs = libs .. "-L" .. linkdir
+ if linkdir ~= path.join(installdir, "lib") then
+ libs = libs .. " -L" .. (linkdir:gsub("\\", "/"))
+ end
end
libs = libs .. " -L${libdir}"
for _, link in ipairs(fetchinfo.links) do
@@ -69,14 +72,16 @@ function _patch_pkgconfig(package)
-- cflags
local cflags = ""
for _, includedir in ipairs(fetchinfo.includedirs) do
- cflags = cflags .. "-I" .. includedir
+ if includedir ~= path.join(installdir, "include") then
+ cflags = cflags .. " -I" .. (includedir:gsub("\\", "/"))
+ end
end
cflags = cflags .. " -I${includedir}"
-- patch a *.pc file
local file = io.open(pcfile, 'w')
if file then
- file:print("prefix=%s", package:installdir())
+ file:print("prefix=%s", installdir:gsub("\\", "/"))
file:print("exec_prefix=${prefix}")
file:print("libdir=${exec_prefix}/lib")
file:print("includedir=${prefix}/include")
@@ -91,6 +96,32 @@ function _patch_pkgconfig(package)
end
end
+-- fix paths for the precompiled package
+-- @see https://github.com/xmake-io/xmake/issues/1671
+function _fix_paths_for_precompiled_package(package)
+ local filepaths = {path.join(package:installdir(), "**.cmake|include/**")}
+ for _, filepath in ipairs(filepaths) do
+ for _, file in ipairs(os.files(filepath)) do
+ io.gsub(file, "(\"(.-)\")", function(_, value)
+ if value:find(package:buildhash(), 1, true) and value:find(package:name(), 1, true) then
+ local result
+ local splitinfo = value:split(package:buildhash(), {plain = true})
+ if #splitinfo == 2 then
+ result = path.join(package:installdir(), splitinfo[2])
+ elseif #splitinfo == 1 then
+ result = package:installdir()
+ end
+ if result then
+ result = result:gsub("\\", "/")
+ vprint("fix path: %s in %s", result, path.filename(file))
+ return "\"" .. result .. "\""
+ end
+ end
+ end)
+ end
+ end
+end
+
-- check package toolchains
function _check_package_toolchains(package)
for _, toolchain_inst in pairs(package:toolchains()) do
@@ -111,7 +142,10 @@ function main(package)
-- enter the working directory
local oldir = nil
- if #package:urls() > 0 then
+ local sourcedir = package:sourcedir()
+ if sourcedir then
+ oldir = os.cd(sourcedir)
+ elseif #package:urls() > 0 then
-- only one root directory? skip it
local filedirs = os.filedirs(path.join(workdir, "source", "*"))
if #filedirs == 1 and os.isdir(filedirs[1]) then
@@ -196,6 +230,11 @@ function main(package)
-- this package is installed now
if installed_now then
+ -- fix paths for the precompiled package
+ if package:is_plat("windows") and not package:is_built() and not package:is_system() then
+ _fix_paths_for_precompiled_package(package)
+ end
+
-- patch pkg-config files for package
_patch_pkgconfig(package)
@@ -247,7 +286,16 @@ function main(package)
-- failed
if not package:requireinfo().optional then
if os.isfile(errorfile) then
- print("if you want to get verbose errors, please see:")
+ if errors then
+ print("")
+ for idx, line in ipairs(errors:split("\n")) do
+ print(line)
+ if idx > 16 then
+ break
+ end
+ end
+ end
+ cprint("if you want to get more verbose errors, please see:")
cprint(" -> ${bright}%s", errorfile)
end
raise("install failed!")
diff --git a/xmake/modules/private/action/require/impl/actions/patch_sources.lua b/xmake/modules/private/action/require/impl/actions/patch_sources.lua
index 23d46f3d3..d5874f8f5 100644
--- a/xmake/modules/private/action/require/impl/actions/patch_sources.lua
+++ b/xmake/modules/private/action/require/impl/actions/patch_sources.lua
@@ -50,6 +50,7 @@ end
function _patch(package, patch_url, patch_hash)
-- trace
+ patch_url = proxy.mirror(patch_url) or patch_url
vprint("patching %s to %s-%s ..", patch_url, package:name(), package:version_str())
-- get the patch file
@@ -72,7 +73,7 @@ function _patch(package, patch_url, patch_hash)
-- download the patch file
if patch_url:find(string.ipattern("https-://")) or patch_url:find(string.ipattern("ftps-://")) then
- http.download(proxy.mirror(patch_url) or patch_url, patch_file)
+ http.download(patch_url, patch_file)
else
-- copy the patch file
if os.isfile(patch_url) then
diff --git a/xmake/modules/private/action/require/impl/install_packages.lua b/xmake/modules/private/action/require/impl/install_packages.lua
index 7e83ae939..f62a0fb52 100644
--- a/xmake/modules/private/action/require/impl/install_packages.lua
+++ b/xmake/modules/private/action/require/impl/install_packages.lua
@@ -25,11 +25,12 @@ import("core.base.scheduler")
import("core.project.project")
import("core.base.tty")
import("private.async.runjobs")
-import("private.utils.progress")
+import("utils.progress")
import("actions.install", {alias = "action_install"})
import("actions.download", {alias = "action_download"})
import("net.fasturl")
import("private.action.require.impl.package")
+import("private.action.require.impl.lock_packages")
import("private.action.require.impl.register_packages")
-- sort packages urls
@@ -242,6 +243,19 @@ function _get_confirm(packages)
return result, packages_modified
end
+-- show upgraded packages
+function _show_upgraded_packages(packages)
+ local upgraded_count = 0
+ for _, instance in ipairs(packages) do
+ local locked_requireinfo = package.get_locked_requireinfo(instance:requireinfo(), {force = true})
+ if locked_requireinfo and locked_requireinfo.version and instance:version() and instance:version():gt(locked_requireinfo.version) then
+ cprint(" ${color.dump.string}%s${clear}: %s -> ${color.success}%s", instance:displayname(), locked_requireinfo.version, instance:version_str())
+ upgraded_count = upgraded_count + 1
+ end
+ end
+ cprint("${bright}%d packages are upgraded!", upgraded_count)
+end
+
-- install packages
function _install_packages(packages_install, packages_download, installdeps)
@@ -254,6 +268,9 @@ function _install_packages(packages_install, packages_download, installdeps)
packages_installed[tostring(instance)] = false
end
+ -- save terminal mode for stdout, @see https://github.com/xmake-io/xmake/issues/1924
+ local term_mode_stdout = tty.term_mode("stdout")
+
-- do install
local progress_helper = show_wait and progress.new() or nil
local packages_installing = {}
@@ -424,6 +441,12 @@ function _install_packages(packages_install, packages_download, installdeps)
end
end
+ -- fix terminal mode to avoid some subprocess to change it
+ -- @see https://github.com/xmake-io/xmake/issues/1924
+ if term_mode_stdout ~= tty.term_mode("stdout") then
+ tty.term_mode("stdout", term_mode_stdout)
+ end
+
-- trace
progress_helper:clear()
tty.erase_line_to_start().cr()
@@ -579,6 +602,11 @@ function main(requires, opt)
end
end
+ -- show upgraded information
+ if option.get("upgrade") then
+ print("upgrading packages ..")
+ end
+
-- some packages are modified? we need fix packages list and all deps
if packages_modified then
order_packages = {}
@@ -600,6 +628,14 @@ function main(requires, opt)
-- re-register and refresh all root packages to local cache,
-- because there may be some missing optional dependencies reinstalled
register_packages(packages)
+
+ -- show upgraded packages
+ if option.get("upgrade") then
+ _show_upgraded_packages(packages)
+ end
+
+ -- lock packages
+ lock_packages(packages)
return packages
end
diff --git a/xmake/modules/private/action/require/impl/lock_packages.lua b/xmake/modules/private/action/require/impl/lock_packages.lua
new file mode 100644
index 000000000..6a962ba77
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/lock_packages.lua
@@ -0,0 +1,72 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file lock_packages.lua
+--
+
+-- imports
+import("core.project.project")
+import("core.project.config")
+import("devel.git")
+import("private.action.require.impl.utils.filter")
+import("private.action.require.impl.utils.requirekey")
+
+-- get locked package key
+function _get_packagelock_key(instance)
+ local requireinfo = instance:requireinfo()
+ return requireinfo and requireinfo.requirekey
+end
+
+-- lock package
+function _lock_package(instance)
+ local result = {}
+ local repo = instance:repo()
+ result.version = instance:version_str()
+ result.branch = instance:branch()
+ result.tag = instance:tag()
+ if repo then
+ local lastcommit
+ local manifest = instance:manifest_load()
+ if manifest and manifest.repo then
+ lastcommit = manifest.repo.commit
+ end
+ if not lastcommit then
+ lastcommit = repo:commit()
+ end
+ result.repo = {url = repo:url(), commit = lastcommit, branch = repo:branch()}
+ end
+ return result
+end
+
+-- lock all required packages
+function main(packages)
+ if project.policy("package.requires_lock") then
+ local plat = config.plat() or os.subhost()
+ local arch = config.arch() or so.subarch()
+ local key = plat .. "|" .. arch
+ local results = os.isfile(project.requireslock()) and io.load(project.requireslock()) or {}
+ results.__meta__ = results.__meta__ or {}
+ results.__meta__.version = project.requireslock_version()
+ results[key] = {}
+ for _, instance in ipairs(packages) do
+ local packagelock_key = _get_packagelock_key(instance)
+ results[key][packagelock_key] = _lock_package(instance)
+ end
+ io.writefile(project.requireslock(), string.serialize(results, {orderkeys = true}))
+ end
+end
+
diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua
index 612911429..1d013b91e 100644
--- a/xmake/modules/private/action/require/impl/package.lua
+++ b/xmake/modules/private/action/require/impl/package.lua
@@ -23,13 +23,15 @@ import("core.base.semver")
import("core.base.option")
import("core.base.global")
import("core.base.hashset")
-import("private.utils.progress")
+import("utils.progress")
import("core.cache.memcache")
import("core.project.project")
+import("core.project.config")
import("core.tool.toolchain")
import("core.package.package", {alias = "core_package"})
import("devel.git")
import("private.action.require.impl.repository")
+import("private.action.require.impl.utils.requirekey", {alias = "_get_requirekey"})
-- get memcache
function _memcache()
@@ -150,8 +152,23 @@ function _load_require(require_str, requires_extra, parentinfo)
-- require packge in the current host platform
if require_extra.host then
- require_extra.plat = os.host()
- require_extra.arch = os.arch()
+ if is_subhost(core_package.targetplat()) and os.subarch() == core_package.targetarch() then
+ -- we need pass plat/arch to avoid repeat installation
+ -- @see https://github.com/xmake-io/xmake/issues/1579
+ else
+ require_extra.plat = os.subhost()
+ require_extra.arch = os.subarch()
+ end
+ end
+
+ -- check require options
+ local extra_options = hashset.of("plat", "arch", "kind", "host", "targetos",
+ "alias", "group", "system", "option", "default", "optional", "debug",
+ "verify", "external", "private", "build", "configs", "version")
+ for name, value in pairs(require_extra) do
+ if not extra_options:has(name) then
+ wprint("add_requires(\"%s\") has unknown option: {%s=%s}!", require_str, name, tostring(value))
+ end
end
-- init required item
@@ -193,13 +210,41 @@ function _load_package_from_project(packagename)
end
-- load package package from repositories
-function _load_package_from_repository(packagename, reponame)
- local packagedir, repo = repository.packagedir(packagename, reponame)
+function _load_package_from_repository(packagename, opt)
+ local packagedir, repo = repository.packagedir(packagename, opt)
if packagedir then
return core_package.load_from_repository(packagename, repo, packagedir)
end
end
+-- has locked requires?
+function _has_locked_requires(opt)
+ opt = opt or {}
+ if not option.get("upgrade") or opt.force then
+ return project.policy("package.requires_lock") and os.isfile(project.requireslock())
+ end
+end
+
+-- get locked requires
+function _get_locked_requires(requirekey, opt)
+ opt = opt or {}
+ local requireslock = _memcache():get("requireslock")
+ if requireslock == nil or opt.force then
+ if _has_locked_requires(opt) then
+ requireslock = io.load(project.requireslock())
+ end
+ _memcache():set("requireslock", requireslock or false)
+ end
+ if requireslock then
+ local plat = config.plat() or os.subhost()
+ local arch = config.arch() or os.subarch()
+ local key = plat .. "|" .. arch
+ if requireslock[key] then
+ return requireslock[key][requirekey], requireslock.__meta__.version
+ end
+ end
+end
+
-- sort package deps
--
-- e.g.
@@ -209,18 +254,39 @@ end
--
-- orderdeps: c -> b -> a
--
-function _sort_packagedeps(package, onlylink)
+function _sort_packagedeps(package)
-- we must use native deps list instead of package:deps() to generate correct linkdeps
local orderdeps = {}
for _, dep in ipairs(package:plaindeps()) do
- if dep and (onlylink ~= true or (dep:is_library() and not dep:is_private())) then
- table.join2(orderdeps, _sort_packagedeps(dep, onlylink))
+ if dep then
+ table.join2(orderdeps, _sort_packagedeps(dep))
table.insert(orderdeps, dep)
end
end
return orderdeps
end
+-- sort link deps
+--
+-- e.g.
+--
+-- a.deps = b
+-- b.deps = c
+--
+-- orderdeps: a -> b -> c
+--
+function _sort_linkdeps(package)
+ -- we must use native deps list instead of package:deps() to generate correct linkdeps
+ local orderdeps = {}
+ for _, dep in ipairs(package:plaindeps()) do
+ if dep and dep:is_library() and not dep:is_private() then
+ table.insert(orderdeps, dep)
+ table.join2(orderdeps, _sort_linkdeps(dep))
+ end
+ end
+ return orderdeps
+end
+
-- add some builtin configurations to package
function _add_package_configurations(package)
-- we can define configs to override it and it's default value in package()
@@ -246,10 +312,22 @@ function _add_package_configurations(package)
end
-- select package version
-function _select_package_version(package, requireinfo)
+function _select_package_version(package, requireinfo, locked_requireinfo)
- -- exists urls? otherwise be phony package (only as package group)
- if #package:urls() > 0 then
+ -- get it from the locked requireinfo
+ if locked_requireinfo then
+ local version = locked_requireinfo.version
+ local source = "version"
+ if locked_requireinfo.branch then
+ source = "branch"
+ elseif locked_requireinfo.tag then
+ source = "tag"
+ end
+ return version, source
+ end
+
+ -- if not phony package (only as package group)
+ if not requireinfo.group then
-- has git url?
local has_giturl = false
@@ -270,14 +348,19 @@ function _select_package_version(package, requireinfo)
-- @see https://github.com/xmake-io/xmake/issues/930
-- https://github.com/xmake-io/xmake/issues/1009
version = require_version
- source = "versions"
+ source = "version"
elseif #package:versions() > 0 then -- select version?
version, source = try { function () return semver.select(require_version, package:versions()) end }
end
- if not version and has_giturl and not require_version:find('.', 1, true) then -- select branch?
- version, source = require_version ~= "latest" and require_version or "master", "branches"
+ if not version and has_giturl and not semver.is_valid(require_version) then -- select branch?
+ version, source = require_version ~= "latest" and require_version or "master", "branch"
end
- if not version then
+ -- local source package? we use a phony version
+ if not version and require_version == "latest" and #package:urls() == 0 then
+ version = "latest"
+ source = "version"
+ end
+ if not version and not package:is_thirdparty() then
raise("package(%s): version(%s) not found!", package:name(), require_version)
end
return version, source
@@ -477,26 +560,17 @@ end
-- get package key
function _get_packagekey(packagename, requireinfo, version)
- local key = packagename .. "/" .. (version or requireinfo.version)
- if requireinfo.plat then
- key = key .. "/" .. requireinfo.plat
- end
- if requireinfo.arch then
- key = key .. "/" .. requireinfo.arch
- end
- if requireinfo.label then
- key = key .. "/" .. requireinfo.label
- end
- local configs = requireinfo.configs
- if configs then
- local configs_order = {}
- for k, v in pairs(configs) do
- table.insert(configs_order, k .. "=" .. tostring(v))
- end
- table.sort(configs_order)
- key = key .. ":" .. string.serialize(configs_order, true)
- end
- return key
+ return _get_requirekey(requireinfo, {name = packagename,
+ plat = requireinfo.plat,
+ arch = requireinfo.arch,
+ version = version or requireinfo.version})
+end
+
+-- get locked package key
+function _get_packagelock_key(requireinfo)
+ local requirestr = requireinfo.originstr
+ local key = _get_requirekey(requireinfo, {hash = true})
+ return string.format("%s#%s", requirestr, key)
end
-- inherit some builtin configs of parent package if these config values are not default value
@@ -520,9 +594,6 @@ function _inherit_parent_configs(requireinfo, package, parentinfo)
if parentinfo.arch then
requireinfo.arch = parentinfo.arch
end
- if parentinfo.private ~= nil then
- requireinfo.private = parentinfo.private
- end
requireinfo_configs.toolchains = requireinfo_configs.toolchains or parentinfo_configs.toolchains
requireinfo_configs.vs_runtime = requireinfo_configs.vs_runtime or parentinfo_configs.vs_runtime
requireinfo.configs = requireinfo_configs
@@ -610,6 +681,13 @@ function _load_package(packagename, requireinfo, opt)
requireinfo.label = splitinfo[2]
end
+ -- save requirekey
+ local requirekey = _get_packagelock_key(requireinfo)
+ requireinfo.requirekey = requirekey
+
+ -- get locked requireinfo
+ local locked_requireinfo = get_locked_requireinfo(requireinfo)
+
-- load package from project first
local package
if os.isfile(os.projectfile()) then
@@ -619,7 +697,8 @@ function _load_package(packagename, requireinfo, opt)
-- load package from repositories
local from_repo = false
if not package then
- package = _load_package_from_repository(packagename, requireinfo.reponame)
+ package = _load_package_from_repository(packagename, {
+ name = requireinfo.reponame, locked_repo = locked_requireinfo and locked_requireinfo.repo})
if package then
from_repo = true
end
@@ -652,7 +731,7 @@ function _load_package(packagename, requireinfo, opt)
_finish_requireinfo(requireinfo, package)
-- select package version
- local version, source = _select_package_version(package, requireinfo)
+ local version, source = _select_package_version(package, requireinfo, locked_requireinfo)
if version then
package:version_set(version, source)
end
@@ -760,7 +839,7 @@ function _load_packages(requires, opt)
package._DEPS = packagedeps
package._PLAINDEPS = plaindeps
package._ORDERDEPS = table.unique(_sort_packagedeps(package))
- package._LINKDEPS = table.unique(_sort_packagedeps(package, true))
+ package._LINKDEPS = table.reverse_unique(_sort_linkdeps(package))
end
end
@@ -889,7 +968,7 @@ function get_configs_str(package)
if type(v) == "boolean" then
table.insert(configs, k .. ":" .. (v and "y" or "n"))
else
- table.insert(configs, k .. ":" .. v)
+ table.insert(configs, k .. ":" .. string.serialize(v, {strip = true, indent = false}))
end
end
end
@@ -898,13 +977,26 @@ function get_configs_str(package)
table.insert(configs, "from:" .. parents_str)
end
local configs_str = #configs > 0 and "[" .. table.concat(configs, ", ") .. "]" or ""
- local limitwidth = os.getwinsize().width * 2 / 3
+ local limitwidth = math.floor(os.getwinsize().width * 2 / 3)
if #configs_str > limitwidth then
configs_str = configs_str:sub(1, limitwidth) .. " ..)"
end
return configs_str
end
+-- get locked requireinfo
+function get_locked_requireinfo(requireinfo, opt)
+ local requirekey = requireinfo.requirekey
+ local locked_requireinfo, requireslock_version
+ if _has_locked_requires(opt) and requirekey then
+ locked_requireinfo, requireslock_version = _get_locked_requires(requirekey, opt)
+ if requireslock_version and semver.compare(project.requireslock_version(), requireslock_version) < 0 then
+ locked_requireinfo = nil
+ end
+ end
+ return locked_requireinfo, requireslock_version
+end
+
-- load requires
function load_requires(requires, requires_extra, opt)
opt = opt or {}
diff --git a/xmake/modules/private/action/require/impl/packagenv.lua b/xmake/modules/private/action/require/impl/packagenv.lua
index 12a98d36f..06a70df91 100644
--- a/xmake/modules/private/action/require/impl/packagenv.lua
+++ b/xmake/modules/private/action/require/impl/packagenv.lua
@@ -33,7 +33,7 @@ function _enter_package(package_name, envs, installdir)
end
end
else
- os.addenv(name, unpack(table.wrap(values)))
+ os.addenv(name, table.unpack(table.wrap(values)))
end
end
end
diff --git a/xmake/modules/private/action/require/impl/register_packages.lua b/xmake/modules/private/action/require/impl/register_packages.lua
index 4c326e770..afc84eb98 100644
--- a/xmake/modules/private/action/require/impl/register_packages.lua
+++ b/xmake/modules/private/action/require/impl/register_packages.lua
@@ -88,16 +88,9 @@ function _register_required_package(instance, required_package)
_register_required_package_base(instance, required_package)
_register_required_package_libs(instance, required_package)
_register_required_package_envs(instance, envs)
- local linkdeps = instance:linkdeps()
- if linkdeps then
- local total = #linkdeps
- for idx, _ in ipairs(linkdeps) do
- local dep = linkdeps[total + 1 - idx]
- if dep then
- if instance:is_library() then
- _register_required_package_libs(dep, required_package, true)
- end
- end
+ for _, dep in ipairs(instance:linkdeps()) do
+ if instance:is_library() then
+ _register_required_package_libs(dep, required_package, true)
end
end
for _, dep in ipairs(instance:orderdeps()) do
diff --git a/xmake/modules/private/action/require/impl/remove_packages.lua b/xmake/modules/private/action/require/impl/remove_packages.lua
index b65627256..f8f93c663 100644
--- a/xmake/modules/private/action/require/impl/remove_packages.lua
+++ b/xmake/modules/private/action/require/impl/remove_packages.lua
@@ -36,7 +36,7 @@ function _get_package_configs_str(manifest_file)
end
end
local configs_str = #configs > 0 and "[" .. table.concat(configs, ", ") .. "]" or ""
- local limitwidth = os.getwinsize().width * 2 / 3
+ local limitwidth = math.floor(os.getwinsize().width * 2 / 3)
if #configs_str > limitwidth then
configs_str = configs_str:sub(1, limitwidth) .. " ..)"
end
diff --git a/xmake/modules/private/action/require/impl/repository.lua b/xmake/modules/private/action/require/impl/repository.lua
index 4dbf44e52..189fad594 100644
--- a/xmake/modules/private/action/require/impl/repository.lua
+++ b/xmake/modules/private/action/require/impl/repository.lua
@@ -19,8 +19,86 @@
--
-- imports
+import("core.base.option")
import("core.base.global")
+import("core.project.config")
import("core.package.repository")
+import("devel.git")
+import("net.proxy")
+
+-- get package directory from the locked repository
+function _get_packagedir_from_locked_repo(packagename, locked_repo)
+
+ -- find global repository directory
+ local repo_global
+ for _, repo in ipairs(repositories()) do
+ if locked_repo.url == repo:url() and locked_repo.branch == repo:branch() then
+ repo_global = repo
+ break
+ end
+ end
+ local reponame = hash.uuid(locked_repo.url):gsub("%-", ""):lower() .. ".lock"
+
+ -- get local repodir
+ local repodir_local
+ if os.isdir(locked_repo.url) then
+ repodir_local = locked_repo.url
+ elseif not locked_repo.commit and repo_global then
+ repodir_local = repo_global:directory()
+ else
+ repodir_local = path.join(config.directory(), "repositories", reponame)
+ end
+
+ -- clone repository to local
+ local lastcommit
+ if not os.isdir(repodir_local) then
+ if repo_global then
+ git.clone(repo_global:directory(), {verbose = option.get("verbose"), outputdir = repodir_local})
+ lastcommit = repo_global:commit()
+ elseif global.get("network") ~= "private" then
+ local remoteurl = proxy.mirror(locked_repo.url) or locked_repo.url
+ git.clone(remoteurl, {verbose = option.get("verbose"), branch = locked_repo.branch, outputdir = repodir_local})
+ else
+ wprint("we cannot lock repository(%s) in private network mode!", locked_repo.url)
+ return
+ end
+ end
+
+ -- lock commit
+ if locked_repo.commit and os.isdir(path.join(repodir_local, ".git")) then
+ lastcommit = lastcommit or try {function()
+ return git.lastcommit({repodir = repodir_local})
+ end}
+ if locked_repo.commit ~= lastcommit then
+ -- try checkout to the given commit
+ local ok = try {function () git.checkout(locked_repo.commit, {verbose = option.get("verbose"), repodir = repodir_local}); return true end}
+ if not ok then
+ if global.get("network") ~= "private" then
+ -- pull the latest commit
+ local remoteurl = proxy.mirror(locked_repo.url) or locked_repo.url
+ git.pull({verbose = option.get("verbose"), remote = remoteurl, branch = locked_repo.branch, repodir = repodir_local})
+ -- re-checkout to the given commit
+ ok = try {function () git.checkout(locked_repo.commit, {verbose = option.get("verbose"), repodir = repodir_local}); return true end}
+ else
+ wprint("we cannot lock repository(%s) in private network mode!", locked_repo.url)
+ return
+ end
+ end
+ end
+ end
+
+ -- find package directory
+ local foundir
+ if ok then
+ local dir = path.join(repodir_local, "packages", packagename:sub(1, 1), packagename)
+ if os.isdir(dir) and os.isfile(path.join(dir, "xmake.lua")) then
+ local repo = repository.load(reponame, locked_repo.url, locked_repo.branch, false)
+ foundir = {dir, repo}
+ vprint("lock package(%s) in %s from repository(%s)/%s", packagename, dir, locked_repo.url, locked_repo.commit)
+ end
+ end
+ return foundir
+end
-- get all repositories
function repositories()
@@ -48,34 +126,66 @@ function pulled()
end
-- get package directory from repositories
-function packagedir(packagename, reponame)
+function packagedir(packagename, opt)
-- strip trailng ~tag, e.g. zlib~debug
+ opt = opt or {}
packagename = packagename:lower()
if packagename:find('~', 1, true) then
packagename = packagename:gsub("~.+$", "")
end
- -- get it from cache it
- local packagedirs = _g._PACKAGEDIRS or {}
- local foundir = packagedirs[packagename]
- if foundir then
- return foundir[1], foundir[2]
+ -- get cache key
+ local reponame = opt.name
+ local cachekey = packagename
+ local locked_repo = opt.locked_repo
+ if locked_repo then
+ cachekey = cachekey .. locked_repo.url .. (locked_repo.commit or "") .. (locked_repo.branch or "")
+ end
+ local packagedirs = _g._PACKAGEDIRS
+ if not packagedirs then
+ packagedirs = {}
+ _g._PACKAGEDIRS = packagedirs
end
- -- find the package directory from repositories
- for _, repo in ipairs(repositories()) do
- local dir = path.join(repo:directory(), "packages", packagename:sub(1, 1), packagename)
- if os.isdir(dir) and os.isfile(path.join(dir, "xmake.lua")) and (not reponame or reponame == repo:name()) then
- foundir = {dir, repo}
- break
+ -- get the package directory
+ local foundir = packagedirs[cachekey]
+ if not foundir then
+
+ -- find the package directory from the locked repository
+ if locked_repo then
+ local dir, repo = _get_packagedir_from_locked_repo(packagename, locked_repo)
+ if dir and repo then
+ foundir = {dir, repo}
+ end
+ end
+
+ -- find the package directory from repositories
+ if not foundir then
+ for _, repo in ipairs(repositories()) do
+ local dir = path.join(repo:directory(), "packages", packagename:sub(1, 1), packagename)
+ if os.isdir(dir) and os.isfile(path.join(dir, "xmake.lua")) and (not reponame or reponame == repo:name()) then
+ foundir = {dir, repo}
+ break
+ end
+ end
end
+ foundir = foundir or {}
+ packagedirs[cachekey] = foundir
end
- if foundir then
- packagedirs[packagename] = foundir
- _g._PACKAGEDIRS = packagedirs
- return foundir[1], foundir[2]
+
+ -- save the current commit
+ local dir = foundir[1]
+ local repo = foundir[2]
+ if repo and not repo:commit() then
+ local lastcommit = try {function()
+ if os.isdir(path.join(repo:directory(), ".git")) then
+ return git.lastcommit({repodir = repo:directory()})
+ end
+ end}
+ repo:commit_set(lastcommit)
end
+ return dir, repo
end
-- get artifacts manifest from repositories
diff --git a/xmake/modules/private/action/require/impl/search_packages.lua b/xmake/modules/private/action/require/impl/search_packages.lua
index 00cf1ffbf..276747db4 100644
--- a/xmake/modules/private/action/require/impl/search_packages.lua
+++ b/xmake/modules/private/action/require/impl/search_packages.lua
@@ -22,7 +22,7 @@
function _search_packages(name)
-- get package manager name
- local manager_name, package_name = unpack(name:split("::", {plain = true, strict = true}))
+ local manager_name, package_name = table.unpack(name:split("::", {plain = true, strict = true}))
if package_name == nil then
package_name = manager_name
manager_name = "xmake"
diff --git a/xmake/modules/private/action/require/impl/utils/requirekey.lua b/xmake/modules/private/action/require/impl/utils/requirekey.lua
new file mode 100644
index 000000000..d1792e50c
--- /dev/null
+++ b/xmake/modules/private/action/require/impl/utils/requirekey.lua
@@ -0,0 +1,60 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file requirekey.lua
+--
+
+-- get require key from requireinfo
+function main(requireinfo, opt)
+ opt = opt or {}
+ local key = ""
+ if opt.name then
+ key = key .. "/" .. opt.name
+ end
+ if opt.plat then
+ key = key .. "/" .. opt.plat
+ end
+ if opt.arch then
+ key = key .. "/" .. opt.arch
+ end
+ if opt.version then
+ key = key .. "/" .. opt.version
+ end
+ if requireinfo.label then
+ key = key .. "/" .. requireinfo.label
+ end
+ if key:startswith("/") then
+ key = key:sub(2)
+ end
+ local configs = requireinfo.configs
+ if configs then
+ local configs_order = {}
+ for k, v in pairs(configs) do
+ table.insert(configs_order, k .. "=" .. tostring(v))
+ end
+ table.sort(configs_order)
+ key = key .. ":" .. string.serialize(configs_order, true)
+ end
+ if opt.hash then
+ if key == "" then
+ key = "_" -- we need generate a fixed hash value
+ end
+ return hash.uuid(key):split("-", {plain = true})[1]:lower()
+ else
+ return key
+ end
+end
diff --git a/xmake/modules/private/action/require/install.lua b/xmake/modules/private/action/require/install.lua
index 821991dee..e27e627cb 100644
--- a/xmake/modules/private/action/require/install.lua
+++ b/xmake/modules/private/action/require/install.lua
@@ -76,7 +76,7 @@ function main(requires_raw)
--
-- attempt to install git from the builtin-packages first if git not found
--
- if git and not repository.pulled() then
+ if git and (not repository.pulled() or option.get("upgrade")) then
task.run("repo", {update = true})
end
diff --git a/xmake/modules/private/action/trybuild/autotools.lua b/xmake/modules/private/action/trybuild/autotools.lua
index 14434f1c5..1d4090522 100644
--- a/xmake/modules/private/action/trybuild/autotools.lua
+++ b/xmake/modules/private/action/trybuild/autotools.lua
@@ -19,7 +19,6 @@
--
-- imports
-import("core.base.cli")
import("core.base.option")
import("core.project.config")
import("core.platform.platform")
@@ -142,7 +141,7 @@ function _get_configs(artifacts_dir)
-- add extra user configs
local tryconfigs = config.get("tryconfigs")
if tryconfigs then
- for _, opt in ipairs(cli.parse(tryconfigs)) do
+ for _, opt in ipairs(os.argv(tryconfigs)) do
table.insert(configs, tostring(opt))
end
end
diff --git a/xmake/modules/private/action/trybuild/cmake.lua b/xmake/modules/private/action/trybuild/cmake.lua
index e2022b7b8..4217e98a5 100644
--- a/xmake/modules/private/action/trybuild/cmake.lua
+++ b/xmake/modules/private/action/trybuild/cmake.lua
@@ -19,7 +19,6 @@
--
-- imports
-import("core.base.cli")
import("core.base.option")
import("core.project.config")
import("core.tool.toolchain")
@@ -199,7 +198,7 @@ function _get_configs(artifacts_dir)
-- add extra user configs
local tryconfigs = config.get("tryconfigs")
if tryconfigs then
- for _, opt in ipairs(cli.parse(tryconfigs)) do
+ for _, opt in ipairs(os.argv(tryconfigs)) do
table.insert(configs, tostring(opt))
end
end
diff --git a/xmake/modules/private/action/trybuild/meson.lua b/xmake/modules/private/action/trybuild/meson.lua
index 312e24d22..f2baaff21 100644
--- a/xmake/modules/private/action/trybuild/meson.lua
+++ b/xmake/modules/private/action/trybuild/meson.lua
@@ -19,7 +19,6 @@
--
-- imports
-import("core.base.cli")
import("core.base.option")
import("core.project.config")
import("lib.detect.find_file")
@@ -47,7 +46,7 @@ function _get_configs(artifacts_dir, buildir)
-- add extra user configs
local tryconfigs = config.get("tryconfigs")
if tryconfigs then
- for _, opt in ipairs(cli.parse(tryconfigs)) do
+ for _, opt in ipairs(os.argv(tryconfigs)) do
table.insert(configs, tostring(opt))
end
end
diff --git a/xmake/modules/private/async/jobpool.lua b/xmake/modules/private/async/jobpool.lua
index 299700534..f7eef0c1b 100644
--- a/xmake/modules/private/async/jobpool.lua
+++ b/xmake/modules/private/async/jobpool.lua
@@ -35,8 +35,23 @@ function jobpool:rootjob()
return self._rootjob
end
+-- new run job
+--
+-- e.g.
+-- local job = jobpool:newjob("xxx", function (index, total) end)
+-- jobpool:add(job, rootjob1)
+-- jobpool:add(job, rootjob2)
+-- jobpool:add(job, rootjob3)
+--
+function jobpool:newjob(name, run)
+ return {name = name, run = run}
+end
+
-- add run job to the given job node
--
+-- e.g.
+-- local job = jobpool:addjob("xxx", function (index, total) end, {rootjob = rootjob})
+--
-- @param name the job name
-- @param run the run command/script
-- @param opt the options (rootjob)
diff --git a/xmake/modules/private/async/runjobs.lua b/xmake/modules/private/async/runjobs.lua
index 0361399dc..a4ea2bc10 100644
--- a/xmake/modules/private/async/runjobs.lua
+++ b/xmake/modules/private/async/runjobs.lua
@@ -20,7 +20,7 @@
-- imports
import("core.base.scheduler")
-import("private.utils.progress")
+import("utils.progress")
-- print back characters
function _print_backchars(backnum)
@@ -37,7 +37,7 @@ end
-- e.g.
-- runjobs("test", function (index) print("hello") end, {total = 100, comax = 6, timeout = 1000, on_timer = function (running_jobs_indices) end})
-- runjobs("test", function () os.sleep(10000) end, { progress = true })
--- runjobs("test", function () os.sleep(10000) end, { progress = { chars = {'/','\'} } }) -- see module private.utils.progress
+-- runjobs("test", function () os.sleep(10000) end, { progress = { chars = {'/','\'} } }) -- see module utils.progress
--
-- local jobs = jobpool.new()
-- local root = jobs:addjob("job/root", function (idx, total)
diff --git a/xmake/modules/private/tools/gcc/parse_deps.lua b/xmake/modules/private/tools/gcc/parse_deps.lua
index cb06d091c..3b682753c 100644
--- a/xmake/modules/private/tools/gcc/parse_deps.lua
+++ b/xmake/modules/private/tools/gcc/parse_deps.lua
@@ -54,9 +54,18 @@ end
-- src/tbox/libc/string/../../prefix/../config.h \
-- build/iphoneos/x86_64/release/tbox.config.h \
--
+-- with c++ modules:
+-- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o: src/foo.mpp\
+-- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o gcm.cache/foo.gcm: bar.c++m cat.c++m\
+-- foo.c++m: gcm.cache/foo.gcm\
+-- .PHONY: foo.c++m\
+-- gcm.cache/foo.gcm:| build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o\
+-- CXX_IMPORTS += bar.c++m cat.c++m\
+--
function main(depsdata)
-- we assume there is only one valid line
+ local block = 0
local results = hashset.new()
local projectdir = os.projectdir()
local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first
@@ -68,8 +77,15 @@ function main(depsdata)
if is_host("windows") and includefile:match("^%w\\:") then
includefile = includefile:replace("\\:", ":", plain)
end
- if not includefile:endswith(":") then -- ignore "xxx.o:" prefix
+ if includefile:endswith(":") then -- ignore "xxx.o:" prefix
+ block = block + 1
+ if block > 1 then
+ -- skip other `xxx.o:` block
+ break
+ end
+ else
includefile = includefile:replace(space_placeholder, ' ', plain)
+ includefile = includefile:split("\n", {plain = true})[1]
if #includefile > 0 then
includefile = _normailize_dep(includefile, projectdir)
if includefile then
diff --git a/xmake/modules/private/utils/batchcmds.lua b/xmake/modules/private/utils/batchcmds.lua
index 371735321..bb5204072 100644
--- a/xmake/modules/private/utils/batchcmds.lua
+++ b/xmake/modules/private/utils/batchcmds.lua
@@ -28,7 +28,7 @@ import("core.theme.theme")
import("core.tool.linker")
import("core.tool.compiler")
import("core.language.language")
-import("private.utils.progress", {alias = "progress_utils"})
+import("utils.progress", {alias = "progress_utils"})
-- define module
local batchcmds = batchcmds or object { _init = {"_TARGET", "_CMDS", "_DEPS", "_tip"}}
@@ -117,6 +117,14 @@ function _runcmd_mkdir(cmd, opt)
end
end
+-- run command: os.cd
+function _runcmd_cd(cmd, opt)
+ local dir = cmd.dir
+ if not opt.dryrun then
+ os.cd(dir)
+ end
+end
+
-- run command: os.rm
function _runcmd_rm(cmd, opt)
local filepath = cmd.filepath
@@ -128,21 +136,21 @@ end
-- run command: os.cp
function _runcmd_cp(cmd, opt)
if not opt.dryrun then
- os.cp(opt.srcpath, opt.dstpath, opt.opt)
+ os.cp(cmd.srcpath, cmd.dstpath, opt.opt)
end
end
-- run command: os.mv
function _runcmd_mv(cmd, opt)
if not opt.dryrun then
- os.mv(opt.srcpath, opt.dstpath, opt.opt)
+ os.mv(cmd.srcpath, cmd.dstpath, opt.opt)
end
end
-- run command: os.ln
function _runcmd_ln(cmd, opt)
if not opt.dryrun then
- os.ln(opt.srcpath, opt.dstpath, opt.opt)
+ os.ln(cmd.srcpath, cmd.dstpath, opt.opt)
end
end
@@ -158,6 +166,7 @@ function _runcmd(cmd, opt)
vrunv = _runcmd_vrunv,
execv = _runcmd_execv,
mkdir = _runcmd_mkdir,
+ cd = _runcmd_cd,
rm = _runcmd_rm,
cp = _runcmd_cp,
mv = _runcmd_mv,
@@ -268,6 +277,11 @@ function batchcmds:ln(srcpath, dstpath, opt)
table.insert(self:cmds(), {kind = "ln", srcpath = srcpath, dstpath = dstpath, opt = opt})
end
+-- add command: os.cd
+function batchcmds:cd(dir, opt)
+ table.insert(self:cmds(), {kind = "cd", dir = dir, opt = opt})
+end
+
-- add command: show
function batchcmds:show(format, ...)
local showtext = string.format(format, ...)
diff --git a/xmake/modules/private/utils/bin2c.lua b/xmake/modules/private/utils/bin2c.lua
index 91ea1eafe..6f18833fc 100644
--- a/xmake/modules/private/utils/bin2c.lua
+++ b/xmake/modules/private/utils/bin2c.lua
@@ -23,9 +23,10 @@ import("core.base.bytes")
import("core.base.option")
local options = {
- {'w', "linewidth", "kv", nil, "Set the line width"},
- {'i', "binarypath", "kv", nil, "Set the binary file path."},
- {'o', "outputpath", "kv", nil, "Set the output file path."}
+ {'w', "linewidth", "kv", nil, "Set the line width"},
+ {nil, "nozeroend", "k", false, "Disable to patch zero terminating character"},
+ {'i', "binarypath", "kv", nil, "Set the binary file path."},
+ {'o', "outputpath", "kv", nil, "Set the output file path."}
}
function _do_dump(binarydata, outputfile, opt)
@@ -84,7 +85,9 @@ function _do_bin2c(binarypath, outputpath, opt)
local binarydata = bytes(io.readfile(binarypath, {encoding = "binary"}))
local outputfile = io.open(outputpath, 'w')
if outputfile then
- binarydata = binarydata .. bytes('\0')
+ if not opt.nozeroend then
+ binarydata = binarydata .. bytes('\0')
+ end
_do_dump(binarydata, outputfile, opt)
outputfile:close()
end
diff --git a/xmake/modules/private/xrepo/action/env.lua b/xmake/modules/private/xrepo/action/env.lua
index cb6936006..bf5b2ec44 100644
--- a/xmake/modules/private/xrepo/action/env.lua
+++ b/xmake/modules/private/xrepo/action/env.lua
@@ -22,6 +22,7 @@
import("core.base.option")
import("core.base.task")
import("core.base.hashset")
+import("core.base.global")
import("core.project.config")
import("core.project.project")
import("core.tool.toolchain")
@@ -47,16 +48,29 @@ function menu_options()
{nil, "show", "k", nil, "Only show environment information." },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo env -f \"vs_runtime=MD\" zlib cmake ..",
+ " - xrepo env -f \"vs_runtime='MD'\" zlib cmake ..",
" - xrepo env -f \"regex=true,thread=true\" \"zlib,boost\" cmake .."},
- {'b', "packages", "kv", nil, "Set the packages to be bound",
+ {nil, "add", "k", nil, "Add global environment config.",
"e.g.",
+ " - xrepo env --add base.lua",
+ " - xrepo env --add myenv.lua"},
+ {nil, "remove", "k", nil, "Remove global environment config.",
+ "e.g.",
+ " - xrepo env --remove base",
+ " - xrepo env --remove myenv"},
+ {"l", "list", "k", nil, "List all global environment configs.",
+ "e.g.",
+ " - xrepo env --list"},
+ {'b', "bind", "kv", nil, "Bind the specified environment or package.",
+ "e.g.",
+ " - xrepo env -b base",
+ " - xrepo env -b myenv",
" - xrepo env -b \"python 3.x\" python",
" - xrepo env -b \"llvm 11.x\" bash",
" $ clang --version",
" - xrepo env -p android -b \"zlib,luajit 2.x\" luajit xx.lua"},
{},
- {nil, "program", "v", nil, "Set the program name to be run",
+ {nil, "program", "v", nil, "Set the program name to be run.",
"e.g.",
" - xrepo env",
" - xrepo env bash",
@@ -70,7 +84,7 @@ function menu_options()
local function show_options()
-- show usage
- cprint("${bright}Usage: $${clear cyan}xrepo env [options] [packages] [program] [arguments]")
+ cprint("${bright}Usage: $${clear cyan}xrepo env [options] [program] [arguments]")
-- show description
print("")
@@ -112,9 +126,10 @@ function _get_requires(packages)
end
-- enter project
-function _enter_project()
+function _enter_project(opt)
-- enter working project directory
+ opt = opt or {}
local workdir = path.join(os.tmpdir(), "xrepo", "working")
if not os.isdir(workdir) then
os.mkdir(workdir)
@@ -123,6 +138,10 @@ function _enter_project()
else
os.cd(workdir)
end
+ if opt.enteronly then
+ project.chdir(workdir)
+ return
+ end
-- do configure first
local config_argv = {"f", "-c"}
@@ -157,7 +176,7 @@ function _enter_project()
end
-- remove repeat environment values
-function _remove_repeat_pathenv(value)
+function _deduplicate_pathenv(value)
if value then
local itemset = {}
local results = {}
@@ -174,6 +193,23 @@ function _remove_repeat_pathenv(value)
return value
end
+-- get environment directory
+function _get_envsdir()
+ return path.join(global.directory(), "envs")
+end
+
+-- get bound environment or packages
+function _get_boundenv(opt)
+ local bind = (opt and opt.bind) or option.get("bind")
+ if bind then
+ local envfile = path.join(_get_envsdir(), bind .. ".lua")
+ if envfile and os.isfile(envfile) then
+ return envfile
+ end
+ end
+ return bind
+end
+
-- add values to environment variable
function _addenvs(envs, name, ...)
local values = {...}
@@ -208,7 +244,7 @@ function _package_addenvs(envs, instance)
end
end
else
- _addenvs(envs, name, unpack(table.wrap(values)))
+ _addenvs(envs, name, table.unpack(table.wrap(values)))
end
end
@@ -227,6 +263,13 @@ function _package_addenvs(envs, instance)
_addenvs(envs, "ACLOCAL_PATH", aclocal)
end
_addenvs(envs, "CMAKE_PREFIX_PATH", installdir)
+ if instance:is_plat("windows") then
+ _addenvs(envs, "INCLUDE", path.join(installdir, "include"))
+ _addenvs(envs, "LIBPATH", path.join(installdir, "lib"))
+ else
+ _addenvs(envs, "CPATH", path.join(installdir, "include"))
+ _addenvs(envs, "LIBRARY_PATH", path.join(installdir, "lib"))
+ end
end
end
@@ -237,36 +280,47 @@ function _toolchain_addenvs(envs)
local toolchain_inst = toolchain.load(name, toolchain_opt)
if toolchain_inst then
for k, v in pairs(toolchain_inst:runenvs()) do
- _addenvs(envs, k, unpack(path.splitenv(v)))
+ _addenvs(envs, k, table.unpack(path.splitenv(v)))
end
end
end
end
-- get package environments
-function _package_getenvs()
+function _package_getenvs(opt)
local envs = os.getenvs()
- if os.isfile(os.projectfile()) and not option.get("packages") then
+ local boundenv = _get_boundenv(opt)
+ local has_envfile = false
+ local packages = nil
+ if boundenv and os.isfile(boundenv) then
+ has_envfile = true
+ else
+ packages = boundenv or option.get("program")
+ end
+ if os.isfile(os.projectfile()) or has_envfile then
+ if not os.isfile(os.projectfile()) then
+ _enter_project({enteronly = true})
+ end
+ if has_envfile then
+ table.insert(project.rcfiles(), boundenv)
+ end
task.run("config", {target = "all"}, {disable_dump = true})
_toolchain_addenvs(envs)
local requires, requires_extra = get_requires()
for _, instance in ipairs(package.load_packages(requires, {requires_extra = requires_extra})) do
_package_addenvs(envs, instance)
end
- else
- local packages = option.get("packages") or option.get("program")
- if packages then
- _enter_project()
- packages = packages:split(',', {plain = true})
- local requires, requires_extra = _get_requires(packages)
- for _, instance in ipairs(package.load_packages(requires, {requires_extra = requires_extra})) do
- _package_addenvs(envs, instance)
- end
+ elseif packages then
+ _enter_project()
+ packages = packages:split(',', {plain = true})
+ local requires, requires_extra = _get_requires(packages)
+ for _, instance in ipairs(package.load_packages(requires, {requires_extra = requires_extra})) do
+ _package_addenvs(envs, instance)
end
end
local results = {}
for k, v in pairs(envs) do
- results[k] = _remove_repeat_pathenv(v)
+ results[k] = _deduplicate_pathenv(v)
end
return results
end
@@ -285,40 +339,66 @@ function _get_env_script(envs, shell, del)
elseif shell == "cmd" then
prefix = "@set \""
suffix = "\""
+ elseif shell:endswith("sh") then
+ if del then
+ prefix = "unset '"
+ connector = "'"
+ else
+ prefix = "export '"
+ connector = "'='"
+ suffix = "'"
+ end
end
+ local exceptions = hashset.of("_", "PS1", "PROMPT", "!;", "!EXITCODE")
local ret = ""
if del then
for name, _ in pairs(envs) do
- ret = ret .. prefix .. name .. connector .. default .. suffix .. "\n"
+ if not exceptions:has(name) then
+ ret = ret .. prefix .. name .. connector .. default .. suffix .. "\n"
+ end
end
else
for name, value in pairs(envs) do
- ret = ret .. prefix .. name .. connector .. value .. suffix .. "\n"
+ if not exceptions:has(name) then
+ ret = ret .. prefix .. name .. connector .. value .. suffix .. "\n"
+ end
end
end
return ret
end
-- get information of current virtual environment
-function info(key)
+function info(key, bnd)
if key == "prompt" then
- assert(os.isfile(os.projectfile()), "xmake.lua not found!")
- print("[%s]", path.filename(os.projectdir()))
+ local boundenv = _get_boundenv({bind = bnd})
+ if boundenv then
+ assert(os.isfile(boundenv), "environment not found!")
+ io.write("[" .. path.basename(boundenv) .. "]")
+ elseif not bnd then
+ assert(os.isfile(os.projectfile()), "xmake.lua not found!")
+ io.write("[" .. path.filename(os.projectdir()) .. "]")
+ end
elseif key == "envfile" then
print(os.tmpfile())
elseif key == "config" then
- if os.isfile(os.projectfile()) then
+ local boundenv = _get_boundenv({bind = bnd})
+ local has_envfile = (boundenv and os.isfile(boundenv)) and true or false
+ if has_envfile or os.isfile(os.projectfile()) then
+ if has_envfile then
+ _enter_project({enteronly = true})
+ table.insert(project.rcfiles(), boundenv)
+ end
task.run("config", {target = "all"}, {disable_dump = true})
end
elseif key:startswith("script.") then
local shell = key:match("script%.(.+)")
- print(_get_env_script(_package_getenvs(), shell, false))
+ io.write(_get_env_script(_package_getenvs({bind = bnd}), shell, false))
elseif key:startswith("backup.") then
local shell = key:match("backup%.(.+)")
-- remove current environment variables first
- print(_get_env_script(_package_getenvs(), shell, true))
- print(_get_env_script(os.getenvs(), shell, false))
+ io.write(_get_env_script(_package_getenvs({bind = bnd}), shell, true))
+ io.write(_get_env_script(os.getenvs(), shell, false))
end
end
@@ -350,18 +430,37 @@ end
-- main entry
function main()
- local envs = _package_getenvs()
- local program = option.get("program")
- if program and not option.get("show") then
- if envs and envs.PATH then
- os.setenv("PATH", envs.PATH)
+ if option.get("list") then
+ print("%s:", _get_envsdir())
+ local count = 0
+ for _, envfile in ipairs(os.files(path.join(_get_envsdir(), "*.lua"))) do
+ local envname = path.basename(envfile)
+ print(" - %s", envname)
+ count = count + 1
end
- if program == "shell" then
- _run_shell(envs)
- else
- os.execv(program, option.get("arguments"), {envs = envs})
+ print("envs(%d) found!", count)
+ elseif option.get("add") then
+ local envfile = assert(option.get("program"), "please set environment config file!")
+ if os.isfile(envfile) then
+ os.vcp(envfile, path.join(_get_envsdir(), path.filename(envfile)))
end
+ elseif option.get("remove") then
+ local envname = assert(option.get("program"), "please set environment config name!")
+ os.rm(path.join(_get_envsdir(), envname .. ".lua"))
else
- print(envs)
+ local envs = _package_getenvs()
+ local program = option.get("program")
+ if program and not option.get("show") then
+ if envs and envs.PATH then
+ os.setenv("PATH", envs.PATH)
+ end
+ if program == "shell" then
+ _run_shell(envs)
+ else
+ os.execv(program, option.get("arguments"), {envs = envs})
+ end
+ else
+ print(envs)
+ end
end
end
diff --git a/xmake/modules/private/xrepo/action/export.lua b/xmake/modules/private/xrepo/action/export.lua
index 4c2e8c445..e6c4b3ffc 100644
--- a/xmake/modules/private/xrepo/action/export.lua
+++ b/xmake/modules/private/xrepo/action/export.lua
@@ -39,7 +39,7 @@ function menu_options()
values = {"release", "debug"} },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo export -f \"vs_runtime=MD\" zlib",
+ " - xrepo export -f \"vs_runtime='MD'\" zlib",
" - xrepo export -f \"regex=true,thread=true\" boost"},
{},
{nil, "shallow", "k", nil, "Does not export dependent packages."},
diff --git a/xmake/modules/private/xrepo/action/fetch.lua b/xmake/modules/private/xrepo/action/fetch.lua
index a577b7c14..57e56c71b 100644
--- a/xmake/modules/private/xrepo/action/fetch.lua
+++ b/xmake/modules/private/xrepo/action/fetch.lua
@@ -38,7 +38,7 @@ function menu_options()
values = {"release", "debug"} },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo fetch --configs=\"vs_runtime=MD\" zlib",
+ " - xrepo fetch --configs=\"vs_runtime='MD'\" zlib",
" - xrepo fetch --configs=\"regex=true,thread=true\" boost"},
{},
{nil, "deps", "k", nil, "Fetch packages with dependencies." },
diff --git a/xmake/modules/private/xrepo/action/import.lua b/xmake/modules/private/xrepo/action/import.lua
index e3805135d..fb7cb15ef 100644
--- a/xmake/modules/private/xrepo/action/import.lua
+++ b/xmake/modules/private/xrepo/action/import.lua
@@ -39,7 +39,7 @@ function menu_options()
values = {"release", "debug"} },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo import -f \"vs_runtime=MD\" zlib",
+ " - xrepo import -f \"vs_runtime='MD'\" zlib",
" - xrepo import -f \"regex=true,thread=true\" boost"},
{},
{'i', "packagedir", "kv", "packages","Set the imported packages directory."},
diff --git a/xmake/modules/private/xrepo/action/info.lua b/xmake/modules/private/xrepo/action/info.lua
index 3258397cf..4d570da19 100644
--- a/xmake/modules/private/xrepo/action/info.lua
+++ b/xmake/modules/private/xrepo/action/info.lua
@@ -38,7 +38,7 @@ function menu_options()
values = {"release", "debug"} },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo fetch --configs=\"vs_runtime=MD\" zlib",
+ " - xrepo fetch --configs=\"vs_runtime='MD'\" zlib",
" - xrepo fetch --configs=\"regex=true,thread=true\" boost"},
{},
{nil, "packages", "vs", nil, "The packages list.",
diff --git a/xmake/modules/private/xrepo/action/install.lua b/xmake/modules/private/xrepo/action/install.lua
index ccd14c839..e14d6701e 100644
--- a/xmake/modules/private/xrepo/action/install.lua
+++ b/xmake/modules/private/xrepo/action/install.lua
@@ -38,9 +38,9 @@ function menu_options()
values = {"release", "debug"} },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo install -f \"vs_runtime=MD\" zlib",
+ " - xrepo install -f \"vs_runtime='MD'\" zlib",
" - xrepo install -f \"regex=true,thread=true\" boost"},
- {'j', "jobs", "kv", tostring(math.ceil(os.cpuinfo().ncpu * 3 / 2)),
+ {'j', "jobs", "kv", tostring(os.default_njob()),
"Set the number of parallel compilation jobs."},
{nil, "linkjobs", "kv", nil, "Set the number of parallel link jobs."},
{nil, "includes", "kv", nil, "Includes extra lua configuration files.",
diff --git a/xmake/modules/private/xrepo/action/remove.lua b/xmake/modules/private/xrepo/action/remove.lua
index 7624fa9cf..c9fce0831 100644
--- a/xmake/modules/private/xrepo/action/remove.lua
+++ b/xmake/modules/private/xrepo/action/remove.lua
@@ -39,7 +39,7 @@ function menu_options()
values = {"release", "debug"} },
{'f', "configs", "kv", nil, "Set the given extra package configs.",
"e.g.",
- " - xrepo remove -f \"vs_runtime=MD\" zlib",
+ " - xrepo remove -f \"vs_runtime='MD'\" zlib",
" - xrepo remove -f \"regex=true,thread=true\" boost"},
{},
{nil, "all", "k", nil, "Remove all packages and ignore extra package configs.",
diff --git a/xmake/modules/target/action/install/cmake_importfiles.lua b/xmake/modules/target/action/install/cmake_importfiles.lua
index 12d044251..1249c9c8b 100644
--- a/xmake/modules/target/action/install/cmake_importfiles.lua
+++ b/xmake/modules/target/action/install/cmake_importfiles.lua
@@ -21,18 +21,33 @@
-- imports
import("core.project.project")
+-- get the lib file of the target
+function _get_libfile(target, installdir)
+ local libfile = path.filename(target:targetfile())
+ if target:is_plat("windows") then
+ libfile = libfile:gsub("%.dll$", ".lib")
+ elseif target:is_plat("mingw") then
+ if os.isfile(path.join(installdir, "lib", libfile:gsub("%.dll$", ".dll.a"))) then
+ libfile = libfile:gsub("%.dll$", ".dll.a")
+ else
+ libfile = libfile:gsub("%.dll$", ".lib")
+ end
+ end
+ return libfile
+end
+
-- get the builtin variables
function _get_builtinvars(target, installdir)
return {TARGETNAME = target:name(),
PROJECTNAME = project.name() or target:name(),
- TARGETFILENAME = path.filename(target:targetfile()),
- TARGETKIND = target:is_shared() and "SHARED" or "STATIC",
+ TARGETFILENAME = target:targetfile() and _get_libfile(target, installdir),
+ TARGETKIND = target:is_headeronly() and "INTERFACE" or (target:is_shared() and "SHARED" or "STATIC"),
PACKAGE_VERSION = target:get("version") or "1.0.0",
TARGET_PTRBYTES = target:is_arch("x86", "i386") and "4" or "8"}
end
--- install cmake import file
-function _install_cmake_importfile(target, installdir, filename, opt)
+-- install cmake config file
+function _install_cmake_configfile(target, installdir, filename, opt)
-- get import file path
local projectname = project.name() or target:name()
@@ -48,6 +63,68 @@ function _install_cmake_importfile(target, installdir, filename, opt)
-- copy and replace builtin variables
local content = io.readfile(importfile_src)
if content then
+ content = content:split("#######################+#")[1]
+ content = content:gsub("(@(.-)@)", function(_, variable)
+ variable = variable:trim()
+ local value = builtinvars[variable]
+ return type(value) == "function" and value() or value
+ end)
+ io.writefile(importfile_dst, content)
+ end
+end
+
+-- append target to cmake config file
+function _append_cmake_configfile(target, installdir, filename, opt)
+
+ -- get import file path
+ local projectname = project.name() or target:name()
+ local importfile_src = path.join(os.programdir(), "scripts", "cmake_importfiles", filename)
+ local importfile_dst = path.join(installdir, opt and opt.libdir or "lib", "cmake", projectname, (filename:gsub("xxx", projectname)))
+
+ -- get the builtin variables
+ local builtinvars = _get_builtinvars(target, installdir)
+
+ -- generate the file if not exist / file is outdated
+ if target:is_headeronly() or not os.isfile(importfile_dst) or os.mtime(importfile_dst) < os.mtime(target:targetfile()) then
+ _install_cmake_configfile(target, installdir, filename, opt)
+ end
+
+ -- copy and replace builtin variables
+ local content = io.readfile(importfile_src)
+ local dst_content = io.readfile(importfile_dst)
+ if content then
+ content = content:split("#######################+#")[2]
+ content = content:gsub("(@(.-)@)", function(_, variable)
+ variable = variable:trim()
+ local value = builtinvars[variable]
+ return type(value) == "function" and value() or value
+ end)
+ content = content:trim()
+
+ -- check if the target already exists
+ if not dst_content:match(format("%sTargets.cmake", target:name())) then
+ io.writefile(importfile_dst, dst_content:trim() .. "\n\n" .. content .. "\n")
+ end
+ end
+end
+
+-- install cmake target file
+function _install_cmake_targetfile(target, installdir, filename, opt)
+
+ -- get import file path
+ local projectname = project.name() or target:name()
+ local importfile_src = path.join(os.programdir(), "scripts", "cmake_importfiles", filename)
+ local importfile_dst = path.join(installdir, opt and opt.libdir or "lib", "cmake", projectname, (filename:gsub("xxx", target:name())))
+
+ -- trace
+ vprint("generating %s ..", importfile_dst)
+
+ -- get the builtin variables
+ local builtinvars = _get_builtinvars(target, installdir)
+
+ -- copy and replace builtin variables
+ local content = io.readfile(importfile_src)
+ if content then
content = content:gsub("(@(.-)@)", function(_, variable)
variable = variable:trim()
local value = builtinvars[variable]
@@ -71,13 +148,15 @@ function main(target, opt)
end
-- do install
- _install_cmake_importfile(target, installdir, "xxxConfig.cmake", opt)
- _install_cmake_importfile(target, installdir, "xxxConfigVersion.cmake", opt)
- _install_cmake_importfile(target, installdir, "xxxTargets.cmake", opt)
- if is_mode("debug") then
- _install_cmake_importfile(target, installdir, "xxxTargets-debug.cmake", opt)
- else
- _install_cmake_importfile(target, installdir, "xxxTargets-release.cmake", opt)
+ _append_cmake_configfile(target, installdir, "xxxConfig.cmake", opt)
+ _install_cmake_configfile(target, installdir, "xxxConfigVersion.cmake", opt)
+ _install_cmake_targetfile(target, installdir, "xxxTargets.cmake", opt)
+ if not target:is_headeronly() then
+ if is_mode("debug") then
+ _install_cmake_targetfile(target, installdir, "xxxTargets-debug.cmake", opt)
+ else
+ _install_cmake_targetfile(target, installdir, "xxxTargets-release.cmake", opt)
+ end
end
end
diff --git a/xmake/modules/target/action/install/main.lua b/xmake/modules/target/action/install/main.lua
index 289d258f0..c115e836e 100644
--- a/xmake/modules/target/action/install/main.lua
+++ b/xmake/modules/target/action/install/main.lua
@@ -20,7 +20,6 @@
-- install files
function _install_files(target)
-
local srcfiles, dstfiles = target:installfiles()
if srcfiles and dstfiles then
local i = 1
@@ -47,12 +46,10 @@ function main(target, opt)
print("installing %s to %s ..", target:name(), installdir)
-- call script
- if not target:is_phony() then
- local install_style = target:is_plat("windows", "mingw") and "windows" or "unix"
- local script = import(install_style, {anonymous = true})["install_" .. target:kind()]
- if script then
- script(target, opt)
- end
+ local install_style = target:is_plat("windows", "mingw") and "windows" or "unix"
+ local script = import(install_style, {anonymous = true})["install_" .. target:kind()]
+ if script then
+ script(target, opt)
end
-- install other files
diff --git a/xmake/modules/target/action/install/pkgconfig_importfiles.lua b/xmake/modules/target/action/install/pkgconfig_importfiles.lua
index 1187bb5e6..979feaee2 100644
--- a/xmake/modules/target/action/install/pkgconfig_importfiles.lua
+++ b/xmake/modules/target/action/install/pkgconfig_importfiles.lua
@@ -24,10 +24,8 @@ function main(target, opt)
-- check
opt = opt or {}
assert(target:is_library(), 'pkgconfig_importfiles: only support for library target(%s)!', target:name())
-
- -- only for unix platform
local installdir = target:installdir()
- if target:is_plat("windows") or not installdir then
+ if not installdir then
return
end
@@ -35,26 +33,32 @@ function main(target, opt)
local pcfile = path.join(installdir, opt and opt.libdir or "lib", "pkgconfig", opt.filename or (target:basename() .. ".pc"))
-- get includedirs
- local includedirs = opt.includedirs or {path.join(installdir, "include")}
+ local includedirs = opt.includedirs
-- get links and linkdirs
local links = opt.links or target:basename()
- local linkdirs = opt.linkdirs or {path.join(installdir, "lib")}
+ local linkdirs = opt.linkdirs
-- get libs
local libs = ""
for _, linkdir in ipairs(linkdirs) do
- libs = libs .. "-L" .. linkdir
+ if linkdir ~= path.join(installdir, "lib") then
+ libs = libs .. " -L" .. (linkdir:gsub("\\", "/"))
+ end
end
libs = libs .. " -L${libdir}"
- for _, link in ipairs(links) do
- libs = libs .. " -l" .. link
+ if not target:is_headeronly() then
+ for _, link in ipairs(links) do
+ libs = libs .. " -l" .. link
+ end
end
-- get cflags
local cflags = ""
for _, includedir in ipairs(includedirs) do
- cflags = cflags .. "-I" .. includedir
+ if includedir ~= path.join(installdir, "include") then
+ cflags = cflags .. " -I" .. (includedir:gsub("\\", "/"))
+ end
end
cflags = cflags .. " -I${includedir}"
@@ -64,7 +68,7 @@ function main(target, opt)
-- generate a *.pc file
local file = io.open(pcfile, 'w')
if file then
- file:print("prefix=%s", installdir)
+ file:print("prefix=%s", installdir:gsub("\\", "/"))
file:print("exec_prefix=${prefix}")
file:print("libdir=${exec_prefix}/lib")
file:print("includedir=${prefix}/include")
@@ -76,7 +80,6 @@ function main(target, opt)
file:print("Version: %s", version)
end
file:print("Libs: %s", libs)
- file:print("Libs.private: ")
file:print("Cflags: %s", cflags)
file:close()
end
diff --git a/xmake/modules/target/action/install/unix.lua b/xmake/modules/target/action/install/unix.lua
index d4311aeea..af641e5bc 100644
--- a/xmake/modules/target/action/install/unix.lua
+++ b/xmake/modules/target/action/install/unix.lua
@@ -18,15 +18,8 @@
-- @file unix.lua
--
--- install library
-function _install_library(target, opt)
-
- -- install libraries
- local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
- os.mkdir(librarydir)
- os.vcp(target:targetfile(), librarydir)
-
- -- install headers
+-- install headers
+function _install_headers(target, opt)
local includedir = path.join(target:installdir(), opt and opt.includedir or "include")
os.mkdir(includedir)
local srcheaders, dstheaders = target:headerfiles(includedir)
@@ -42,19 +35,99 @@ function _install_library(target, opt)
end
end
+-- install shared libraries for package
+function _install_shared_for_package(target, pkg, outputdir)
+ _g.installed_libfiles = _g.installed_libfiles or {}
+ for _, sopath in ipairs(table.wrap(pkg:get("libfiles"))) do
+ if sopath:endswith(".so") or sopath:match(".+%.so%..+$") or sopath:endswith(".dylib") then
+ -- prevent packages using the same system libfiles from overwriting each other
+ if not _g.installed_libfiles[sopath] then
+ local soname = path.filename(sopath)
+ local targetname = path.join(outputdir, soname)
+ if os.isfile(targetname) then
+ wprint("'%s' already exists in install dir, overwriting it from package(%s).", soname, pkg:name())
+ -- rm because symlink cannot overwrite existing file
+ os.rm(targetname)
+ end
+ -- we need reserve symlink
+ -- @see https://github.com/xmake-io/xmake/issues/1582
+ os.vcp(sopath, outputdir, {symlink = true})
+ _g.installed_libfiles[sopath] = true
+ end
+ end
+ end
+end
+
+-- install shared libraries for packages
+function _install_shared_for_packages(target, outputdir)
+ _g.installed_packages = _g.installed_packages or {}
+ for _, pkg in ipairs(target:orderpkgs()) do
+ if not _g.installed_packages[pkg:name()] then
+ if pkg:enabled() and pkg:get("libfiles") then
+ _install_shared_for_package(target, pkg, outputdir)
+ end
+ _g.installed_packages[pkg:name()] = true
+ end
+ end
+end
+
-- install binary
function install_binary(target, opt)
+
+ -- install binary
local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin")
os.mkdir(binarydir)
os.vcp(target:targetfile(), binarydir)
+
+ -- install libraries
+ local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
+ os.mkdir(librarydir)
+
+ -- install the dependent shared (*.so) target
+ -- @see https://github.com/xmake-io/xmake/issues/961
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:kind() == "shared" then
+ local depfile = dep:targetfile()
+ if os.isfile(depfile) then
+ os.vcp(depfile, librarydir)
+ end
+ end
+ -- install all shared libraries in packages in all deps
+ _install_shared_for_packages(dep, librarydir)
+ end
+
+ -- install shared libraries for all packages
+ _install_shared_for_packages(target, librarydir)
end
-- install shared library
function install_shared(target, opt)
- _install_library(target, opt)
+
+ -- install libraries
+ local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
+ os.mkdir(librarydir)
+ os.vcp(target:targetfile(), librarydir)
+
+ -- install shared libraries for all packages
+ _install_shared_for_packages(target, librarydir)
+
+ -- install headers
+ _install_headers(target, opt)
end
-- install static library
function install_static(target, opt)
- _install_library(target, opt)
+
+ -- install libraries
+ local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
+ os.mkdir(librarydir)
+ os.vcp(target:targetfile(), librarydir)
+
+ -- install headers
+ _install_headers(target, opt)
+end
+
+-- install headeronly library
+function install_headeronly(target, opt)
+ _install_headers(target, opt)
end
diff --git a/xmake/modules/target/action/install/windows.lua b/xmake/modules/target/action/install/windows.lua
index 73e8f5ee3..dfbcad11f 100644
--- a/xmake/modules/target/action/install/windows.lua
+++ b/xmake/modules/target/action/install/windows.lua
@@ -40,12 +40,18 @@ end
-- install shared libraries for package
function _install_shared_for_package(target, pkg, outputdir)
+ _g.installed_dllfiles = _g.installed_dllfiles or {}
for _, dllpath in ipairs(table.wrap(pkg:get("libfiles"))) do
if dllpath:endswith(".dll") then
- if os.isfile(path.join(outputdir, dllname)) then
- wprint("'%s' already exists in install dir, overwriting it from package(%s).", dllname, pkg:name())
+ -- prevent packages using the same libfiles from overwriting each other
+ if not _g.installed_dllfiles[dllpath] then
+ local dllname = path.filename(dllpath)
+ if os.isfile(path.join(outputdir, dllname)) then
+ wprint("'%s' already exists in install dir, overwriting it from package(%s).", dllname, pkg:name())
+ end
+ os.vcp(dllpath, outputdir)
+ _g.installed_dllfiles[dllpath] = true
end
- os.vcp(dllpath, outputdir)
end
end
end
@@ -70,14 +76,19 @@ function install_binary(target, opt)
local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin")
os.mkdir(binarydir)
os.vcp(target:targetfile(), binarydir)
+ os.trycp(target:symbolfile(), binarydir)
-- install the dependent shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/961
+ _g.installed_dllfiles = _g.installed_dllfiles or {}
for _, dep in ipairs(target:orderdeps()) do
if dep:kind() == "shared" then
local depfile = dep:targetfile()
if os.isfile(depfile) then
- os.vcp(depfile, binarydir)
+ if not _g.installed_dllfiles[depfile] then
+ os.vcp(depfile, binarydir)
+ _g.installed_dllfiles[depfile] = true
+ end
end
end
-- install all shared libraries in packages in all deps
@@ -95,12 +106,13 @@ function install_shared(target, opt)
local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin")
os.mkdir(binarydir)
os.vcp(target:targetfile(), binarydir)
+ os.trycp(target:symbolfile(), binarydir)
-- install *.lib for shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/714
local targetfile = target:targetfile()
local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
- local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. ".lib")
+ local targetfile_lib = path.join(path.directory(targetfile), path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib"))
if os.isfile(targetfile_lib) then
os.mkdir(librarydir)
os.vcp(targetfile_lib, librarydir)
@@ -120,7 +132,13 @@ function install_static(target, opt)
local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
os.mkdir(librarydir)
os.vcp(target:targetfile(), librarydir)
+ os.trycp(target:symbolfile(), librarydir)
-- install headers
_install_headers(target, opt)
end
+
+-- install headeronly
+function install_headeronly(target, opt)
+ _install_headers(target, opt)
+end
diff --git a/xmake/modules/target/action/uninstall/unix.lua b/xmake/modules/target/action/uninstall/unix.lua
index b582aecf6..e11446dd4 100644
--- a/xmake/modules/target/action/uninstall/unix.lua
+++ b/xmake/modules/target/action/uninstall/unix.lua
@@ -18,14 +18,8 @@
-- @file unix.lua
--
--- uninstall library
-function _uninstall_library(target, opt)
-
- -- remove the target file
- local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
- os.vrm(path.join(librarydir, path.filename(target:targetfile())))
-
- -- remove headers from the include directory
+-- uninstall headers
+function _uninstall_headers(target, opt)
local includedir = path.join(target:installdir(), opt and opt.includedir or "include")
local _, dstheaders = target:headerfiles(includedir)
for _, dstheader in ipairs(dstheaders) do
@@ -33,18 +27,76 @@ function _uninstall_library(target, opt)
end
end
+-- uninstall shared libraries for package
+function _uninstall_shared_for_package(target, pkg, outputdir)
+ for _, sopath in ipairs(table.wrap(pkg:get("libfiles"))) do
+ if sopath:endswith(".so") or sopath:endswith(".dylib") then
+ local soname = path.filename(sopath)
+ os.vrm(path.join(outputdir, soname))
+ end
+ end
+end
+
+-- uninstall shared libraries for packages
+function _uninstall_shared_for_packages(target, outputdir)
+ _g.uninstalled_packages = _g.uninstalled_packages or {}
+ for _, pkg in ipairs(target:orderpkgs()) do
+ if not _g.uninstalled_packages[pkg:name()] then
+ if pkg:enabled() and pkg:get("libfiles") then
+ _uninstall_shared_for_package(target, pkg, outputdir)
+ end
+ _g.uninstalled_packages[pkg:name()] = true
+ end
+ end
+end
+
-- uninstall binary
function uninstall_binary(target, opt)
+
+ -- remove the target file
local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin")
os.vrm(path.join(binarydir, path.filename(target:targetfile())))
+
+ -- remove the dependent shared (*.so) target
+ -- @see https://github.com/xmake-io/xmake/issues/961
+ local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:kind() == "shared" then
+ os.vrm(path.join(librarydir, path.filename(dep:targetfile())))
+ end
+ _uninstall_shared_for_packages(dep, librarydir)
+ end
+
+ -- uninstall shared libraries for packages
+ _uninstall_shared_for_packages(target, librarydir)
end
-- uninstall shared library
function uninstall_shared(target, opt)
- _uninstall_library(target, opt)
+
+ -- remove the target file
+ local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
+ os.vrm(path.join(librarydir, path.filename(target:targetfile())))
+
+ -- remove headers from the include directory
+ _uninstall_headers(target, opt)
+
+ -- uninstall shared libraries for packages
+ _uninstall_shared_for_packages(target, librarydir)
end
-- uninstall static library
function uninstall_static(target, opt)
- _uninstall_library(target, opt)
+
+ -- remove the target file
+ local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
+ os.vrm(path.join(librarydir, path.filename(target:targetfile())))
+
+ -- remove headers from the include directory
+ _uninstall_headers(target, opt)
+end
+
+-- uninstall headeronly library
+function uninstall_headeronly(target, opt)
+ _uninstall_headers(target, opt)
end
diff --git a/xmake/modules/target/action/uninstall/windows.lua b/xmake/modules/target/action/uninstall/windows.lua
index f45028303..ed6923567 100644
--- a/xmake/modules/target/action/uninstall/windows.lua
+++ b/xmake/modules/target/action/uninstall/windows.lua
@@ -31,6 +31,7 @@ end
function _uninstall_shared_for_package(target, pkg, outputdir)
for _, dllpath in ipairs(table.wrap(pkg:get("libfiles"))) do
if dllpath:endswith(".dll") then
+ local dllname = path.filename(dllpath)
os.vrm(path.join(outputdir, dllname))
end
end
@@ -55,6 +56,7 @@ function uninstall_binary(target, opt)
-- remove the target file
local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin")
os.vrm(path.join(binarydir, path.filename(target:targetfile())))
+ os.tryrm(path.join(binarydir, path.filename(target:symbolfile())))
-- remove the dependent shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/961
@@ -75,12 +77,13 @@ function uninstall_shared(target, opt)
-- remove the target file
local binarydir = path.join(target:installdir(), opt and opt.bindir or "bin")
os.vrm(path.join(binarydir, path.filename(target:targetfile())))
+ os.tryrm(path.join(binarydir, path.filename(target:symbolfile())))
-- remove *.lib for shared/windows (*.dll) target
-- @see https://github.com/xmake-io/xmake/issues/714
local targetfile = target:targetfile()
local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
- os.vrm(path.join(librarydir, path.basename(targetfile) .. ".lib"))
+ os.vrm(path.join(librarydir, path.basename(targetfile) .. (target:is_plat("mingw") and ".dll.a" or ".lib")))
-- remove headers from the include directory
_uninstall_headers(target, opt)
@@ -95,7 +98,13 @@ function uninstall_static(target, opt)
-- remove the target file
local librarydir = path.join(target:installdir(), opt and opt.libdir or "lib")
os.vrm(path.join(librarydir, path.filename(target:targetfile())))
+ os.tryrm(path.join(librarydir, path.filename(target:symbolfile())))
-- remove headers from the include directory
_uninstall_headers(target, opt)
end
+
+-- uninstall headeronly library
+function uninstall_headeronly(target, opt)
+ _uninstall_headers(target, opt)
+end
diff --git a/xmake/modules/utils/archive/extension.lua b/xmake/modules/utils/archive/extension.lua
index 3a8554efd..fe33a395f 100644
--- a/xmake/modules/utils/archive/extension.lua
+++ b/xmake/modules/utils/archive/extension.lua
@@ -23,7 +23,6 @@ import("core.base.hashset")
-- get the archive extension
function main(archivefile)
-
local extension = ""
local filename = path.filename(archivefile)
local extensionset = hashset.from({".zip", ".7z", ".gz", ".xz", ".tgz", ".bz2", ".tar", ".tar.gz", ".tar.xz", ".tar.bz2"})
@@ -33,5 +32,5 @@ function main(archivefile)
if p and extensionset:has(filename:sub(p)) then i = p end
extension = filename:sub(i)
end
- return extension
+ return extensionset:has(extension) and extension or ""
end
diff --git a/xmake/modules/utils/archive/extract.lua b/xmake/modules/utils/archive/extract.lua
index 4e54bc4dc..d4a41e542 100644
--- a/xmake/modules/utils/archive/extract.lua
+++ b/xmake/modules/utils/archive/extract.lua
@@ -43,16 +43,23 @@ function _extract_using_tar(archivefile, outputdir, extension, opt)
return false
end
- -- on msys2/cygwin? we need translate input path to cygwin-like path
- if is_subhost("msys", "cygwin") and program:gsub("\\", "/"):find("/usr/bin") then
- archivefile = path.cygwin_path(archivefile)
- end
-
-- init argv
local argv = {}
- if is_subhost("windows") then
+ if is_host("windows") then
-- force "x:\\xx" as local file
- table.insert(argv, "--force-local")
+ local force_local = _g.force_local
+ if force_local == nil then
+ force_local = try {function ()
+ local result = os.iorunv(program, {"--help"})
+ if result and result:find("--force-local", 1, true) then
+ return true
+ end
+ end}
+ _g.force_local = force_local or false
+ end
+ if force_local then
+ table.insert(argv, "--force-local")
+ end
end
table.insert(argv, option.get("verbose") and "-xvf" or "-xf")
table.insert(argv, archivefile)
@@ -78,14 +85,10 @@ function _extract_using_tar(archivefile, outputdir, extension, opt)
-- extract it
if is_host("windows") then
- local oldir = os.cd(outputdir)
- os.vrunv(program, argv)
- os.cd(oldir)
+ os.vrunv(program, argv, {curdir = outputdir})
else
os.vrunv(program, argv)
end
-
- -- ok
return true
end
@@ -98,6 +101,12 @@ function _extract_using_7z(archivefile, outputdir, extension, opt)
return false
end
+ -- p7zip cannot extract other archive format on msys/cygwin
+ -- https://github.com/xmake-io/xmake/issues/1575#issuecomment-898205462
+ if is_subhost("msys", "cygwin") and extension ~= ".7z" and program:startswith("sh ") then
+ return false
+ end
+
-- extract to *.tar file first
local outputdir_old = nil
if extension:startswith(".tar.") or extension == ".tgz" then
@@ -140,7 +149,7 @@ function _extract_using_7z(archivefile, outputdir, extension, opt)
-- remove unused pax_global_header file after extracting .tar file
if extension == ".tar" then
os.tryrm(path.join(outputdir, "pax_global_header"))
- os.tryrm(path.join(outputdir, "PaxHeaders.*"))
+ os.tryrm(path.join(outputdir, "PaxHeaders*"))
os.tryrm(path.join(outputdir, "@PaxHeader"))
end
@@ -151,8 +160,6 @@ function _extract_using_7z(archivefile, outputdir, extension, opt)
return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
end
end
-
- -- ok
return true
end
@@ -192,14 +199,8 @@ function _extract_using_gzip(archivefile, outputdir, extension, opt)
os.cp(archivefile, tmpfile)
end
- -- enter outputdir
- local oldir = os.cd(outputdir)
-
-- extract it
- os.vrunv(program, argv)
-
- -- leave outputdir
- os.cd(oldir)
+ os.vrunv(program, argv, {curdir = outputdir})
-- continue to extract *.tar file
if outputdir_old then
@@ -208,8 +209,6 @@ function _extract_using_gzip(archivefile, outputdir, extension, opt)
return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
end
end
-
- -- ok
return true
end
@@ -249,14 +248,8 @@ function _extract_using_xz(archivefile, outputdir, extension, opt)
os.cp(archivefile, tmpfile)
end
- -- enter outputdir
- local oldir = os.cd(outputdir)
-
-- extract it
- os.vrunv(program, argv)
-
- -- leave outputdir
- os.cd(oldir)
+ os.vrunv(program, argv, {curdir = outputdir})
-- continue to extract *.tar file
if outputdir_old then
@@ -265,8 +258,6 @@ function _extract_using_xz(archivefile, outputdir, extension, opt)
return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
end
end
-
- -- ok
return true
end
@@ -320,8 +311,6 @@ function _extract_using_unzip(archivefile, outputdir, extension, opt)
return _extract(tarfile, outputdir_old, ".tar", {_extract_using_tar, _extract_using_7z}, opt)
end
end
-
- -- ok
return true
end
@@ -366,14 +355,8 @@ function _extract_using_bzip2(archivefile, outputdir, extension, opt)
os.cp(archivefile, tmpfile)
end
- -- enter outputdir
- local oldir = os.cd(outputdir)
-
-- extract it
- os.vrunv(program, argv)
-
- -- leave outputdir
- os.cd(oldir)
+ os.vrunv(program, argv, {curdir = outputdir})
-- continue to extract *.tar file
if outputdir_old then
@@ -382,22 +365,16 @@ function _extract_using_bzip2(archivefile, outputdir, extension, opt)
return _extract(tarfile, outputdir_old, ".tar", {_extract_using_7z, _extract_using_tar}, opt)
end
end
-
- -- ok
return true
end
-- extract archive file using extractors
function _extract(archivefile, outputdir, extension, extractors, opt)
-
- -- extract it
for _, extract in ipairs(extractors) do
if extract(archivefile, outputdir, extension, opt) then
return true
end
end
-
- -- failed
return false
end
@@ -417,7 +394,7 @@ function main(archivefile, outputdir, opt)
-- init extractors
local extractors
- if is_host("windows") then
+ if is_subhost("windows") then
-- we use 7z first, becase xmake package has builtin 7z program on windows
-- tar/windows can not extract .bz2 ...
extractors =
@@ -432,6 +409,7 @@ function main(archivefile, outputdir, opt)
, [".tar.gz"] = {_extract_using_7z, _extract_using_gzip}
, [".tar.xz"] = {_extract_using_7z, _extract_using_xz}
, [".tar.bz2"] = {_extract_using_7z, _extract_using_bzip2}
+ , [".tar.lz"] = {_extract_using_7z}
}
else
extractors =
@@ -446,6 +424,7 @@ function main(archivefile, outputdir, opt)
, [".tar.gz"] = {_extract_using_tar, _extract_using_7z, _extract_using_gzip}
, [".tar.xz"] = {_extract_using_tar, _extract_using_7z, _extract_using_xz}
, [".tar.bz2"] = {_extract_using_tar, _extract_using_7z, _extract_using_bzip2}
+ , [".tar.lz"] = {_extract_using_tar, _extract_using_7z}
}
end
diff --git a/xmake/modules/utils/archive/merge_staticlib.lua b/xmake/modules/utils/archive/merge_staticlib.lua
new file mode 100644
index 000000000..dc0130219
--- /dev/null
+++ b/xmake/modules/utils/archive/merge_staticlib.lua
@@ -0,0 +1,73 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file merge_staticlib.lua
+--
+
+-- imports
+import("core.base.option")
+import("private.tools.vstool")
+
+-- merge *.a archive libraries for ar
+function _merge_for_ar(target, program, outputfile, libraryfiles, opt)
+ opt = opt or {}
+ if target:is_plat("macosx", "iphoneos", "watchos", "appletvos") then
+ os.vrunv("libtool", table.join("-static", "-o", outputfile, libraryfiles))
+ else
+ local tmpfile = os.tmpfile()
+ local mrifile = io.open(tmpfile, "w")
+ mrifile:print("create %s", outputfile)
+ for _, libraryfile in ipairs(libraryfiles) do
+ mrifile:print("addlib %s", libraryfile)
+ end
+ mrifile:print("save")
+ mrifile:print("end")
+ mrifile:close()
+ os.vrunv(program, {"-M"}, {stdin = tmpfile})
+ os.rm(tmpfile)
+ end
+end
+
+-- merge *.a archive libraries for msvc/lib.exe
+function _merge_for_msvclib(target, program, outputfile, libraryfiles, opt)
+ opt = opt or {}
+ vstool.runv(program, table.join("-nologo", "-out:" .. outputfile, libraryfiles), {envs = opt.runenvs})
+end
+
+-- merge *.a archive libraries
+function main(target, outputfile, libraryfiles)
+ local program, toolname = target:tool("ar")
+ if program and toolname then
+ if toolname:find("ar") then
+ _merge_for_ar(target, program, outputfile, libraryfiles)
+ elseif toolname == "link" and target:is_plat("windows") then
+ local msvc
+ for _, toolchain_inst in ipairs(target:toolchains()) do
+ if toolchain_inst:name() == "msvc" then
+ msvc = toolchain_inst
+ break
+ end
+ end
+ _merge_for_msvclib(target, (program:gsub("link%.exe", "lib.exe")), outputfile, libraryfiles, {runenvs = msvc and msvc:runenvs()})
+ else
+ raise("cannot merge (%s): unknown ar tool %s!", table.concat(libraryfiles, ", "), toolname)
+ end
+ else
+ raise("cannot merge (%s): ar not found!", table.concat(libraryfiles, ", "))
+ end
+end
+
diff --git a/xmake/modules/private/utils/progress.lua b/xmake/modules/utils/progress.lua
index 5c08cbf8f..074046a69 100644
--- a/xmake/modules/private/utils/progress.lua
+++ b/xmake/modules/utils/progress.lua
@@ -75,6 +75,7 @@ end
-- show the message with process
function show(progress, format, ...)
+ progress = math.floor(progress)
local progress_prefix = "${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} "
if option.get("verbose") then
cprint(progress_prefix .. "${dim}" .. format, progress, ...)
@@ -113,6 +114,7 @@ end
-- get the message text with process
function text(progress, format, ...)
+ progress = math.floor(progress)
local progress_prefix = "${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} "
if option.get("verbose") then
return string.format(progress_prefix .. "${dim}" .. format, progress, ...)
diff --git a/xmake/platforms/linux/xmake.lua b/xmake/platforms/linux/xmake.lua
index 7ba068687..ab7c71f75 100644
--- a/xmake/platforms/linux/xmake.lua
+++ b/xmake/platforms/linux/xmake.lua
@@ -40,7 +40,7 @@ platform("linux")
set_installdir("/usr/local")
-- set toolchains
- set_toolchains("envs", "cross", "gcc", "clang", "yasm", "nasm", "fasm", "cuda", "dlang", "go", "rust", "gfortran", "zig")
+ set_toolchains("envs", "cross", "gcc", "clang", "yasm", "nasm", "fasm", "cuda", "dlang", "go", "rust", "gfortran", "zig", "fpc", "nim")
-- set menu
set_menu {
diff --git a/xmake/platforms/macosx/xmake.lua b/xmake/platforms/macosx/xmake.lua
index 2ff9a10b6..8571a13c4 100644
--- a/xmake/platforms/macosx/xmake.lua
+++ b/xmake/platforms/macosx/xmake.lua
@@ -40,7 +40,7 @@ platform("macosx")
set_installdir("/usr/local")
-- set toolchains
- set_toolchains("envs", "xcode", "clang", "gcc", "yasm", "nasm", "cuda", "dlang", "rust", "go", "gfortran", "zig")
+ set_toolchains("envs", "xcode", "clang", "gcc", "yasm", "nasm", "cuda", "dlang", "rust", "go", "gfortran", "zig", "fpc", "nim")
-- set menu
set_menu {
diff --git a/xmake/platforms/mingw/xmake.lua b/xmake/platforms/mingw/xmake.lua
index b856cf876..b86786a0f 100644
--- a/xmake/platforms/mingw/xmake.lua
+++ b/xmake/platforms/mingw/xmake.lua
@@ -31,9 +31,9 @@ platform("mingw")
set_archs("i386", "x86_64", "arm", "arm64")
-- set formats
- set_formats("static", "$(name).lib")
+ set_formats("static", "lib$(name).a")
set_formats("object", "$(name).obj")
- set_formats("shared", "$(name).dll")
+ set_formats("shared", "lib$(name).dll")
set_formats("binary", "$(name).exe")
set_formats("symbol", "$(name).pdb")
diff --git a/xmake/platforms/windows/xmake.lua b/xmake/platforms/windows/xmake.lua
index fb075adbe..f7687f44b 100644
--- a/xmake/platforms/windows/xmake.lua
+++ b/xmake/platforms/windows/xmake.lua
@@ -38,7 +38,7 @@ platform("windows")
set_formats("symbol", "$(name).pdb")
-- set toolchains
- set_toolchains("msvc", "clang", "yasm", "nasm", "cuda", "dlang", "rust", "go", "gfortran", "zig")
+ set_toolchains("msvc", "clang", "yasm", "nasm", "cuda", "dlang", "rust", "go", "gfortran", "zig", "fpc", "nim")
-- set menu
set_menu {
diff --git a/xmake/plugins/lua/main.lua b/xmake/plugins/lua/main.lua
index 40b16249e..cf0ed80a1 100644
--- a/xmake/plugins/lua/main.lua
+++ b/xmake/plugins/lua/main.lua
@@ -122,7 +122,7 @@ function _run_script(script, args)
if _is_callable(func) then
local result = table.pack(func(table.unpack(args, 1, args.n)))
if printresult and result and result.n ~= 0 then
- utils.dump(unpack(result, 1, result.n))
+ utils.dump(table.unpack(result, 1, result.n))
end
else
-- dump variables directly
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
index eb30a1ee4..a3f893d90 100644
--- a/xmake/plugins/project/clang/compile_commands.lua
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -34,8 +34,13 @@ end
-- https://github.com/xmake-io/xmake/issues/1050
function _translate_arguments(arguments)
local args = {}
- local is_msvc = path.basename(arguments[1]):lower() == "cl"
- for _, arg in ipairs(arguments) do
+ local cc = path.basename(arguments[1]):lower()
+ local is_include = false
+ for idx, arg in ipairs(arguments) do
+ -- see https://github.com/xmake-io/xmake/issues/1721
+ if idx == 1 and is_host("windows") and path.extension(arg) == "" then
+ arg = arg .. ".exe"
+ end
if arg:find("-isystem", 1, true) then
arg = arg:replace("-isystem", "-I")
elseif arg:find("[%-/]external:I") then
@@ -49,8 +54,26 @@ function _translate_arguments(arguments)
end
-- @see use msvc-style flags for msvc to support language-server better
-- https://github.com/xmake-io/xmake/issues/1284
- if is_msvc and arg and arg:startswith("-") then
+ if cc == "cl" and arg and arg:startswith("-") then
arg = arg:gsub("^%-", "/")
+ elseif cc == "nvcc" and arg then
+ -- support -I path with spaces for nvcc
+ -- https://github.com/xmake-io/xmake/issues/1726
+ if is_include then
+ if arg and arg:find(' ', 1, true) then
+ arg = "\"" .. arg .. "\""
+ end
+ is_include = false
+ elseif arg:startswith("-I") then
+ local f = arg:sub(1, 2)
+ local v = arg:sub(3)
+ if v and v:find(' ', 1, true) then
+ arg = f .. "\"" .. v .. "\""
+ end
+ end
+ end
+ if arg == "-I" then
+ is_include = true
end
if arg then
table.insert(args, arg)
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 6259effed..7cbffc699 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -22,7 +22,9 @@
import("core.project.project")
import("core.tool.compiler")
import("core.base.semver")
+import("core.project.rule")
import("lib.detect.find_tool")
+import("private.utils.batchcmds")
-- get minimal cmake version
function _get_cmake_minver()
@@ -67,12 +69,17 @@ end
-- add project info
function _add_project(cmakelists)
+ local cmake_version = _get_cmake_minver()
cmakelists:print([[# this is the build file for project %s
# it is autogenerated by the xmake build system.
# do not edit by hand.
]], project.name() or "")
cmakelists:print("# project")
- cmakelists:print("cmake_minimum_required(VERSION %s)", _get_cmake_minver())
+ cmakelists:print("cmake_minimum_required(VERSION %s)", cmake_version)
+ if cmake_version:ge("3.15.0") then
+ -- for MSVC_RUNTIME_LIBRARY
+ cmakelists:print("cmake_policy(SET CMP0091 NEW)")
+ end
local project_name = project.name()
if not project_name then
for _, target in pairs(project.targets()) do
@@ -126,6 +133,11 @@ function _add_target_shared(cmakelists, target)
cmakelists:print("set_target_properties(%s PROPERTIES LIBRARY_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path(target:targetdir()))
end
+-- add target: headeronly
+function _add_target_headeronly(cmakelists, target)
+ cmakelists:print("add_library(%s INTERFACE)", target:name())
+end
+
-- add target dependencies
function _add_target_dependencies(cmakelists, target)
local deps = target:get("deps")
@@ -141,8 +153,13 @@ end
-- add target sources
function _add_target_sources(cmakelists, target)
cmakelists:print("target_sources(%s PRIVATE", target:name())
- for _, sourcefile in ipairs(target:sourcefiles()) do
- cmakelists:print(" " .. _get_unix_path(sourcefile))
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" then
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ cmakelists:print(" " .. _get_unix_path(sourcefile))
+ end
+ end
end
for _, headerfile in ipairs(target:headerfiles()) do
cmakelists:print(" " .. _get_unix_path(headerfile))
@@ -150,6 +167,18 @@ function _add_target_sources(cmakelists, target)
cmakelists:print(")")
end
+-- add target precompilied header
+function _add_target_precompiled_header(cmakelists, target)
+ local precompiled_header = target:get("pcheader") or target:get("pcxxheader")
+ if precompiled_header then
+ cmakelists:print("target_precompile_headers(%s PRIVATE", target:name())
+ cmakelists:print(" $<$<COMPILE_LANGUAGE:%s>:${CMAKE_CURRENT_SOURCE_DIR}/%s>",
+ target:get("pcxxheader") and "CXX" or "C",
+ _get_unix_path(precompiled_header))
+ cmakelists:print(")")
+ end
+end
+
-- add target include directories
function _add_target_include_directories(cmakelists, target)
local includedirs = _get_configs_from_target(target, "includedirs")
@@ -221,22 +250,14 @@ function _add_target_compile_options(cmakelists, target)
if #cflags > 0 or #cxflags > 0 or #cxxflags > 0 or #cuflags > 0 then
cmakelists:print("target_compile_options(%s PRIVATE", target:name())
for _, flag in ipairs(cflags) do
- if compiler.has_flags("c", flag, {target = target}) then
- cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
- end
+ cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
end
for _, flag in ipairs(cxflags) do
- if compiler.has_flags("c", flag, {target = target}) then
- cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
- end
- if compiler.has_flags("cxx", flag, {target = target}) then
- cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
- end
+ cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
+ cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
end
for _, flag in ipairs(cxxflags) do
- if compiler.has_flags("cxx", flag, {target = target}) then
- cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
- end
+ cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
end
for _, flag in ipairs(cuflags) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:CUDA>:" .. flag .. ">")
@@ -375,6 +396,29 @@ function _add_target_optimization(cmakelists, target)
end
end
+-- add target vs runtime
+--
+-- https://github.com/xmake-io/xmake/issues/1661#issuecomment-927979489
+-- https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html
+--
+function _add_target_vs_runtime(cmakelists, target)
+ local cmake_minver = _get_cmake_minver()
+ if cmake_minver:ge("3.15.0") then
+ local vs_runtime = target:get("runtimes")
+ if vs_runtime then
+ cmakelists:print("if(MSVC)")
+ if vs_runtime:startswith("MT") then
+ vs_runtime = "MultiThreaded$<$<CONFIG:Debug>:Debug>"
+ elseif vs_runtime:startswith("MD") then
+ vs_runtime = "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"
+ end
+ cmakelists:print(' set_property(TARGET %s PROPERTY', target:name())
+ cmakelists:print(' MSVC_RUNTIME_LIBRARY "%s")', vs_runtime)
+ cmakelists:print("endif()")
+ end
+ end
+end
+
-- add target link libraries
function _add_target_link_libraries(cmakelists, target)
@@ -428,24 +472,166 @@ end
-- add target link options
function _add_target_link_options(cmakelists, target)
- local ldflags = _get_configs_from_target(target, "ldflags")
- local shflags = _get_configs_from_target(target, "shflags")
+ local ldflags = _get_configs_from_target(target, "ldflags")
+ local shflags = _get_configs_from_target(target, "shflags")
if #ldflags > 0 or #shflags > 0 then
- local cmake_minver = _get_cmake_minver()
- if cmake_minver:ge("3.13.0") then
- cmakelists:print("target_link_options(%s PRIVATE", target:name())
- else
- cmakelists:print("target_link_libraries(%s PRIVATE", target:name())
- end
+ local flags = {}
for _, flag in ipairs(table.unique(table.join(ldflags, shflags))) do
if target:linker():has_flags(flag) then
+ table.insert(flags, flag)
+ end
+ end
+ if #flags > 0 then
+ local cmake_minver = _get_cmake_minver()
+ if cmake_minver:ge("3.13.0") then
+ cmakelists:print("target_link_options(%s PRIVATE", target:name())
+ else
+ cmakelists:print("target_link_libraries(%s PRIVATE", target:name())
+ end
+ for _, flag in ipairs(flags) do
cmakelists:print(" " .. flag)
end
+ cmakelists:print(")")
+ end
+ end
+end
+
+-- get command string
+function _get_command_string(cmd)
+ local kind = cmd.kind
+ local opt = cmd.opt
+ if cmd.program then
+ local command = os.args(table.join(cmd.program, cmd.argv))
+ if opt and opt.curdir then
+ command = "${CMAKE_COMMAND} -E chdir \"" .. opt.curdir .. "\" " .. command
+ end
+ return command
+ elseif kind == "cp" then
+ if os.isdir(cmd.srcpath) then
+ return string.format("${CMAKE_COMMAND} -E copy_directory %s %s", cmd.srcpath, cmd.dstpath)
+ else
+ return string.format("${CMAKE_COMMAND} -E copy %s %s", cmd.srcpath, cmd.dstpath)
end
+ elseif kind == "rm" then
+ return string.format("${CMAKE_COMMAND} -E rm -rf %s", cmd.filepath)
+ elseif kind == "mv" then
+ return string.format("${CMAKE_COMMAND} -E rename %s %s", cmd.srcpath, cmd.dstpath)
+ elseif kind == "cd" then
+ return string.format("cd %s", cmd.dir)
+ elseif kind == "mkdir" then
+ return string.format("${CMAKE_COMMAND} -E make_directory %s", cmd.dir)
+ elseif kind == "show" then
+ return string.format("echo %s", cmd.showtext)
+ end
+end
+
+-- add custom command
+function _add_target_custom_command(cmakelists, target, command, suffix)
+ if suffix == "before" then
+ -- ADD_CUSTOM_COMMAND and PRE_BUILD did not work as I expected,
+ -- so we need use add_dependencies and fake target to support it.
+ --
+ -- @see https://gitlab.kitware.com/cmake/cmake/-/issues/17802
+ --
+ local key = target:name() .. "_" .. hash.uuid():split("-", {plain = true})[1]
+ cmakelists:print("add_custom_command(OUTPUT output_%s", key)
+ cmakelists:print(" COMMAND %s", command)
+ cmakelists:print(" VERBATIM")
+ cmakelists:print(")")
+ cmakelists:print("add_custom_target(target_%s", key)
+ cmakelists:print(" DEPENDS output_%s", key)
cmakelists:print(")")
+ cmakelists:print("add_dependencies(%s target_%s)", target:name(), key)
+ else
+ cmakelists:print("add_custom_command(TARGET %s", target:name())
+ if suffix == "after" then
+ cmakelists:print(" POST_BUILD")
+ end
+ cmakelists:print(" COMMAND %s", command)
+ cmakelists:print(" VERBATIM")
+ cmakelists:print(")")
+ end
+end
+
+-- add target custom commands for target
+function _add_target_custom_commands_for_target(cmakelists, target, suffix)
+ for _, ruleinst in ipairs(target:orderules()) do
+ local scriptname = "buildcmd" .. (suffix and ("_" .. suffix) or "")
+ local script = ruleinst:script(scriptname)
+ if script then
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ _add_target_custom_command(cmakelists, target, command, suffix)
+ end
+ end
+ end
+ end
end
end
+-- add target custom commands for object rules
+function _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, suffix)
+
+ -- get rule
+ local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!")
+ local ruleinst = assert(project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename)
+
+ -- generate commands for xx_buildcmd_files
+ local scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "")
+ local script = ruleinst:script(scriptname)
+ if script then
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, sourcebatch, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ _add_target_custom_command(cmakelists, target, command, suffix)
+ end
+ end
+ end
+ end
+
+ -- generate commands for xx_buildcmd_file
+ if not script then
+ scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "")
+ script = ruleinst:script(scriptname)
+ if script then
+ local sourcekind = sourcebatch.sourcekind
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, sourcefile, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ _add_target_custom_command(cmakelists, target, command, suffix)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+-- add target custom commands
+function _add_target_custom_commands(cmakelists, target)
+ _add_target_custom_commands_for_target(cmakelists, target, "before")
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind ~= "cc" and sourcekind ~= "cxx" and sourcekind ~= "as" then
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, "before")
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch)
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, "after")
+ end
+ end
+ _add_target_custom_commands_for_target(cmakelists, target, "after")
+end
+
-- TODO export target headers (deprecated)
function _export_target_headers(target)
local srcheaders, dstheaders = target:headers()
@@ -477,6 +663,10 @@ function _add_target(cmakelists, target)
_add_target_static(cmakelists, target)
elseif targetkind == "shared" then
_add_target_shared(cmakelists, target)
+ elseif targetkind == 'headeronly' then
+ _add_target_headeronly(cmakelists, target)
+ _add_target_include_directories(cmakelists, target)
+ return
else
raise("unknown target kind %s", target:kind())
end
@@ -487,6 +677,9 @@ function _add_target(cmakelists, target)
-- add target dependencies
_add_target_dependencies(cmakelists, target)
+ -- add target precompilied header
+ _add_target_precompiled_header(cmakelists, target)
+
-- add target include directories
_add_target_include_directories(cmakelists, target)
@@ -511,6 +704,9 @@ function _add_target(cmakelists, target)
-- add target optimization
_add_target_optimization(cmakelists, target)
+ -- add vs runtime for msvc
+ _add_target_vs_runtime(cmakelists, target)
+
-- add target link libraries
_add_target_link_libraries(cmakelists, target)
@@ -520,6 +716,9 @@ function _add_target(cmakelists, target)
-- add target link options
_add_target_link_options(cmakelists, target)
+ -- add target custom commands
+ _add_target_custom_commands(cmakelists, target)
+
-- add target sources
_add_target_sources(cmakelists, target)
diff --git a/xmake/plugins/project/make/makefile.lua b/xmake/plugins/project/make/makefile.lua
index 6b94cf992..601f920c9 100644
--- a/xmake/plugins/project/make/makefile.lua
+++ b/xmake/plugins/project/make/makefile.lua
@@ -33,7 +33,7 @@ end
-- mkdir directory
function _mkdir(makefile, dir)
- if is_plat("windows") then
+ if is_subhost("windows") then
makefile:print("\t-@mkdir %s > NUL 2>&1", dir)
else
makefile:print("\t@mkdir -p %s", dir)
@@ -42,7 +42,7 @@ end
-- copy file
function _cp(makefile, sourcefile, targetfile)
- if is_plat("windows") then
+ if is_subhost("windows") then
makefile:print("\t@copy /Y %s %s > NUL 2>&1", sourcefile, targetfile)
else
makefile:print("\t@cp %s %s", sourcefile, targetfile)
@@ -51,7 +51,7 @@ end
-- try to remove the given file or directory
function _tryrm(makefile, filedir)
- if is_plat("windows") then
+ if is_subhost("windows") then
-- we attempt to delete it as file first, we remove it as directory if failed
makefile:print("\t@del /F /Q %s > NUL 2>&1 || rmdir /S /Q %s > NUL 2>&1", filedir, filedir)
else
@@ -109,7 +109,7 @@ function _make_common_flags(target, sourcekind, sourcebatch)
-- make common flags
local commonflags = {}
for _, flag in ipairs(first_flags) do
- if flags_stats[flag] == files_count then
+ if flags_stats[flag] >= files_count then
table.insert(commonflags, flag)
end
end
@@ -119,7 +119,7 @@ function _make_common_flags(target, sourcekind, sourcebatch)
for sourcefile, flags in pairs(sourceflags) do
local otherflags = {}
for _, flag in ipairs(flags) do
- if flags_stats[flag] ~= files_count then
+ if flags_stats[flag] < files_count then
table.insert(otherflags, flag)
end
end
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index da0dd9317..4c5fc86f8 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -20,6 +20,7 @@
-- imports
import("core.base.option")
+import("core.project.rule")
import("core.project.config")
import("core.project.project")
import("core.platform.platform")
@@ -32,8 +33,61 @@ import("vs201x_vcxproj_filters")
import("core.cache.memcache")
import("core.cache.localcache")
import("private.action.require.install", {alias = "install_requires"})
+import("private.action.run.make_runenvs")
import("actions.config.configfiles", {alias = "generate_configfiles", rootdir = os.programdir()})
import("actions.config.configheader", {alias = "generate_configheader", rootdir = os.programdir()})
+import("private.utils.batchcmds")
+
+-- escape special chars in msbuild file
+function _escape(str)
+ if not str then
+ return nil
+ end
+
+ local map =
+ {
+ ["%"] = "%25" -- Referencing metadata
+ , ["$"] = "%24" -- Referencing properties
+ , ["@"] = "%40" -- Referencing item lists
+ , ["'"] = "%27" -- Conditions and other expressions
+ , [";"] = "%3B" -- List separator
+ , ["?"] = "%3F" -- Wildcard character for file names in Include and Exclude attributes
+ , ["*"] = "%2A" -- Wildcard character for use in file names in Include and Exclude attributes
+ -- html entities
+ , ["\""] = "&quot;"
+ , ["<"] = "&lt;"
+ , [">"] = "&gt;"
+ , ["&"] = "&amp;"
+ }
+
+ return (string.gsub(str, "[%%%$@';%?%*\"<>&]", function (c) return assert(map[c]) end))
+end
+
+function _make_dirs(dir, vcxprojdir)
+ if dir == nil then
+ return ""
+ end
+ if type(dir) == "string" then
+ dir = path.translate(dir)
+ if dir == "" then
+ return ""
+ end
+ if path.is_absolute(dir) then
+ if dir:startswith(project.directory()) then
+ return _escape(path.relative(dir, vcxprojdir))
+ end
+ return _escape(dir)
+ else
+ return _escape(path.relative(path.absolute(dir), vcxprojdir))
+ end
+ end
+ local r = {}
+ for k, v in ipairs(dir) do
+ r[k] = _make_dirs(v, vcxprojdir)
+ end
+ r = table.unique(r)
+ return path.joinenv(r)
+end
-- clear cache configuration
function _clear_cacheconf()
@@ -47,8 +101,138 @@ function _clear_cacheconf()
localcache.save()
end
+-- get command string
+function _get_command_string(cmd)
+ local kind = cmd.kind
+ local opt = cmd.opt
+ if cmd.program then
+ local command = os.args(table.join(cmd.program, cmd.argv))
+ if opt and opt.curdir then
+ command = string.format("pushd \"%s\"\n%s\npopd", opt.curdir, command)
+ end
+ return command
+ elseif kind == "cp" then
+ return string.format("copy /Y \"%s\" \"%s\"", cmd.srcpath, cmd.dstpath)
+ elseif kind == "rm" then
+ return string.format("del /F /Q \"%s\" || rmdir /S /Q \"%s\"", cmd.filepath, cmd.filepath)
+ elseif kind == "mv" then
+ return string.format("rename \"%s\" \"%s\"", cmd.srcpath, cmd.dstpath)
+ elseif kind == "cd" then
+ return string.format("cd \"%s\"", cmd.dir)
+ elseif kind == "mkdir" then
+ return string.format("if not exist \"%s\" mkdir \"%s\"", cmd.dir, cmd.dir)
+ elseif kind == "show" then
+ return string.format("echo %s", cmd.showtext)
+ end
+end
+
+-- add target custom commands for target
+function _make_custom_commands_for_target(commands, target, suffix)
+ for _, ruleinst in ipairs(target:orderules()) do
+ local scriptname = "buildcmd" .. (suffix and ("_" .. suffix) or "")
+ local script = ruleinst:script(scriptname)
+ if script then
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ local key = suffix and suffix or "before"
+ commands[key] = commands[key] or {}
+ table.insert(commands[key], command)
+ end
+ end
+ end
+ end
+
+ scriptname = "linkcmd" .. (suffix and ("_" .. suffix) or "")
+ script = ruleinst:script(scriptname)
+ if script then
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ local key = (suffix and suffix or "before") .. "_link"
+ commands[key] = commands[key] or {}
+ table.insert(commands[key], command)
+ end
+ end
+ end
+ end
+ end
+end
+
+-- add target custom commands for object rules
+function _make_custom_commands_for_objectrules(commands, target, sourcebatch, suffix)
+
+ -- get rule
+ local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!")
+ local ruleinst = assert(project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename)
+
+ -- generate commands for xx_buildcmd_files
+ local scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "")
+ local script = ruleinst:script(scriptname)
+ if script then
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, sourcebatch, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ local key = suffix and suffix or "before"
+ commands[key] = commands[key] or {}
+ table.insert(commands[key], command)
+ end
+ end
+ end
+ end
+
+ -- generate commands for xx_buildcmd_file
+ if not script then
+ scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "")
+ script = ruleinst:script(scriptname)
+ if script then
+ local sourcekind = sourcebatch.sourcekind
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local batchcmds_ = batchcmds.new({target = target})
+ script(target, batchcmds_, sourcefile, {})
+ if not batchcmds_:empty() then
+ for _, cmd in ipairs(batchcmds_:cmds()) do
+ local command = _get_command_string(cmd)
+ if command then
+ local key = suffix and suffix or "before"
+ commands[key] = commands[key] or {}
+ table.insert(commands[key], command)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+-- make custom commands
+function _make_custom_commands(target)
+ local commands = {}
+ _make_custom_commands_for_target(commands, target, "before")
+ _make_custom_commands_for_target(commands, target)
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind ~= "cc" and sourcekind ~= "cxx" and sourcekind ~= "as" then
+ _make_custom_commands_for_objectrules(commands, target, sourcebatch, "before")
+ _make_custom_commands_for_objectrules(commands, target, sourcebatch)
+ _make_custom_commands_for_objectrules(commands, target, sourcebatch, "after")
+ end
+ end
+ _make_custom_commands_for_target(commands, target, "after")
+ return commands
+end
+
-- make target info
-function _make_targetinfo(mode, arch, target)
+function _make_targetinfo(mode, arch, target, vcxprojdir)
-- init target info
local targetinfo = { mode = mode, arch = (arch == "x86" and "Win32" or "x64") }
@@ -68,6 +252,9 @@ function _make_targetinfo(mode, arch, target)
target:set("pcheader", nil)
target:set("pcxxheader", nil)
+ -- save languages
+ targetinfo.languages = table.wrap(target:get("languages"))
+
-- save symbols
targetinfo.symbols = target:get("symbols")
@@ -111,6 +298,47 @@ function _make_targetinfo(mode, arch, target)
local linkflags = linker.linkflags(target:kind(), target:sourcekinds(), {target = target})
targetinfo.linkflags = linkflags
+ -- save execution dir (when executed from VS)
+ targetinfo.rundir = target:rundir()
+
+ -- save runenvs
+ local runenvs = {}
+ local addrunenvs, setrunenvs = make_runenvs(target)
+ for k, v in pairs(target:pkgenvs()) do
+ addrunenvs = addrunenvs or {}
+ addrunenvs[k] = table.join(table.wrap(addrunenvs[k]), path.splitenv(v))
+ end
+ for _, dep in ipairs(target:orderdeps()) do
+ for k, v in pairs(dep:pkgenvs()) do
+ addrunenvs = addrunenvs or {}
+ addrunenvs[k] = table.join(table.wrap(addrunenvs[k]), path.splitenv(v))
+ end
+ end
+ for k, v in pairs(addrunenvs) do
+ if k:upper() == "PATH" then
+ runenvs[k] = format("%s;$([System.Environment]::GetEnvironmentVariable('%s'))", _make_dirs(v, vcxprojdir), k)
+ else
+ runenvs[k] = format("%s;$([System.Environment]::GetEnvironmentVariable('%s'))", path.joinenv(v), k)
+ end
+ end
+ for k, v in pairs(setrunenvs) do
+ if #v == 1 then
+ v = v[1]
+ if path.is_absolute(v) and v:startswith(project.directory()) then
+ runenvs[k] = _make_dirs(v, vcxprojdir)
+ else
+ runenvs[k] = v[1]
+ end
+ else
+ runenvs[k] = path.joinenv(v)
+ end
+ end
+ local runenvstr = {}
+ for k, v in pairs(runenvs) do
+ table.insert(runenvstr, k .. "=" .. v)
+ end
+ targetinfo.runenvs = table.concat(runenvstr, "\n")
+
-- use mfc? save the mfc runtime kind
if target:rule("win.sdk.mfc.shared_app") or target:rule("win.sdk.mfc.shared") then
targetinfo.usemfc = "Dynamic"
@@ -126,6 +354,9 @@ function _make_targetinfo(mode, arch, target)
end
end
+ -- save custom commands
+ targetinfo.commands = _make_custom_commands(target)
+
-- ok
return targetinfo
end
@@ -324,6 +555,9 @@ function make(outputdir, vsinfo)
-- make target with the given mode and arch
targets[targetname] = targets[targetname] or {}
local _target = targets[targetname]
+
+ -- the vcxproj directory
+ _target.project_dir = path.join(vsinfo.solution_dir, targetname)
-- save c/c++ precompiled header
_target.pcheader = target:pcheaderfile("c") -- header.h
@@ -334,7 +568,7 @@ function make(outputdir, vsinfo)
_target.kind = target:kind()
_target.scriptdir = target:scriptdir()
_target.info = _target.info or {}
- table.insert(_target.info, _make_targetinfo(mode, arch, target))
+ table.insert(_target.info, _make_targetinfo(mode, arch, target, _target.project_dir))
-- save all sourcefiles and headerfiles
_target.sourcefiles = table.unique(table.join(_target.sourcefiles or {}, (target:sourcefiles())))
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
index b1bd6f764..2cc84ff52 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
@@ -19,19 +19,37 @@
--
-- imports
+import("core.project.rule")
import("core.project.config")
+import("core.project.project")
import("core.language.language")
+import("core.tool.toolchain")
+import("private.utils.batchcmds")
import("vsfile")
+function _make_dirs(dir, vcxprojdir)
+ dir = dir:trim()
+ if #dir == 0 then
+ return ""
+ end
+ dir = path.translate(dir)
+ if not path.is_absolute(dir) then
+ dir = path.relative(path.absolute(dir), vcxprojdir)
+ end
+ return dir
+end
+
-- get toolset version
function _get_toolset_ver(targetinfo, vsinfo)
-- get toolset version from vs version
local toolset_ver = nil
- local vs_toolset = config.get("vs_toolset")
+ local vs_toolset = toolchain.load("msvc"):config("vs_toolset") or config.get("vs_toolset")
if vs_toolset then
local verinfo = vs_toolset:split('%.')
- toolset_ver = "v" .. verinfo[1] .. (verinfo[2] or "0")
+ if #verinfo >= 2 then
+ toolset_ver = "v" .. verinfo[1] .. (verinfo[2]:sub(1, 1) or "0")
+ end
end
if not toolset_ver then
toolset_ver = vsinfo.toolset_version
@@ -60,18 +78,16 @@ function _make_compcmd(compargv, sourcefile, objectfile, vcxprojdir)
end
v = v:gsub("__sourcefile__", sourcefile)
v = v:gsub("__objectfile__", objectfile)
+
-- -Idir or /Idir
- v = v:gsub("([%-/]I)(.*)", function (I, dir)
- dir = dir:trim()
- if #dir == 0 then
- return ""
- end
- dir = path.translate(dir)
- if not path.is_absolute(dir) then
- dir = path.relative(path.absolute(dir), vcxprojdir)
- end
- return I .. dir
+ -- handle external includes as well
+ for _, pattern in ipairs({"[%-/](I)(.*)", "[%-/](external:I)(.*)"}) do
+ v = v:gsub(pattern, function (flag, dir)
+ dir = _make_dirs(dir, vcxprojdir)
+ return "/" .. flag .. dir
end)
+ end
+
table.insert(argv, v)
end
return table.concat(argv, " ")
@@ -84,18 +100,15 @@ function _make_compflags(sourcefile, targetinfo, vcxprojdir)
local flags = {}
for _, flag in ipairs(targetinfo.compflags[sourcefile]) do
- -- -Idir or /Idir
- flag = flag:gsub("[%-/]I(.*)", function (dir)
- dir = dir:trim()
- if #dir == 0 then
- return ""
- end
- dir = path.translate(dir)
- if not path.is_absolute(dir) then
- dir = path.relative(path.absolute(dir), vcxprojdir)
- end
- return "/I" .. dir
- end)
+ -- handle external includes as well
+ for _, pattern in ipairs({"[%-/](I)(.*)", "[%-/](external:I)(.*)"}) do
+
+ -- -Idir or /Idir
+ flag = flag:gsub(pattern, function (flag, dir)
+ dir = _make_dirs(dir, vcxprojdir)
+ return "/" .. flag .. dir
+ end)
+ end
-- save flag
table.insert(flags, flag)
@@ -118,29 +131,15 @@ function _make_linkflags(targetinfo, vcxprojdir)
-- replace -libpath:dir or /libpath:dir
flag = flag:gsub(string.ipattern("[%-/]libpath:(.*)"), function (dir)
- dir = dir:trim()
- if #dir == 0 then
- return ""
- end
- dir = path.translate(dir)
- if not path.is_absolute(dir) then
- dir = path.relative(path.absolute(dir), vcxprojdir)
- end
- return "/libpath:" .. dir
- end)
+ dir = _make_dirs(dir, vcxprojdir)
+ return "/libpath:" .. dir
+ end)
-- replace -def:dir or /def:dir
flag = flag:gsub(string.ipattern("[%-/]def:(.*)"), function (dir)
- dir = dir:trim()
- if #dir == 0 then
- return ""
- end
- dir = path.translate(dir)
- if not path.is_absolute(dir) then
- dir = path.relative(path.absolute(dir), vcxprojdir)
- end
- return "/def:" .. dir
- end)
+ dir = _make_dirs(dir, vcxprojdir)
+ return "/def:" .. dir
+ end)
-- save flag
table.insert(flags, flag)
@@ -167,7 +166,7 @@ function _make_tailer(vcxprojfile, vsinfo)
end
-- make Configurations
-function _make_configurations(vcxprojfile, vsinfo, target, vcxprojdir)
+function _make_configurations(vcxprojfile, vsinfo, target)
-- the target name
local targetname = target.name
@@ -234,14 +233,31 @@ function _make_configurations(vcxprojfile, vsinfo, target, vcxprojdir)
-- make OutputDirectory and IntermediateDirectory
for _, targetinfo in ipairs(target.info) do
vcxprojfile:enter("<PropertyGroup Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">", targetinfo.mode, targetinfo.arch)
- vcxprojfile:print("<OutDir>%s\\</OutDir>", path.relative(path.absolute(targetinfo.targetdir), vcxprojdir))
- vcxprojfile:print("<IntDir>%s\\</IntDir>", path.relative(path.absolute(targetinfo.objectdir), vcxprojdir))
+ vcxprojfile:print("<OutDir>%s\\</OutDir>", _make_dirs(targetinfo.targetdir, target.project_dir))
+ vcxprojfile:print("<IntDir>%s\\</IntDir>", _make_dirs(targetinfo.objectdir, target.project_dir))
vcxprojfile:print("<TargetName>%s</TargetName>", path.basename(targetinfo.targetfile))
vcxprojfile:print("<TargetExt>%s</TargetExt>", path.extension(targetinfo.targetfile))
if target.kind == "binary" then
vcxprojfile:print("<LinkIncremental>true</LinkIncremental>")
end
+
+ -- handle ExternalIncludePath (should we handle IncludePath here too?)
+ local externaldirs = {}
+ for _, flag in ipairs(targetinfo.commonflags) do
+ flag:gsub("[%-/]external:I(.*)", function (dir) table.insert(externaldirs, dir) end)
+ end
+ if #externaldirs > 0 then
+ vcxprojfile:print("<ExternalIncludePath>%s;$(VC_IncludePath);$(WindowsSDK_IncludePath);</ExternalIncludePath>", table.concat(externaldirs, ";"))
+ end
+ vcxprojfile:leave("</PropertyGroup>")
+ end
+
+ -- make Debugger
+ for _, targetinfo in ipairs(target.info) do
+ vcxprojfile:enter("<PropertyGroup Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\" Label=\"Debugger\">", targetinfo.mode, targetinfo.arch)
+ vcxprojfile:print("<LocalDebuggerWorkingDirectory>%s</LocalDebuggerWorkingDirectory>", _make_dirs(targetinfo.rundir, target.project_dir))
+ vcxprojfile:print("<LocalDebuggerEnvironment>%s;$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>", targetinfo.runenvs)
vcxprojfile:leave("</PropertyGroup>")
end
end
@@ -282,6 +298,8 @@ function _make_source_options(vcxprojfile, flags, condition)
vcxprojfile:print("<WarningLevel%s>Level2</WarningLevel>", condition)
elseif flagstr:find("[%-/]W3") then
vcxprojfile:print("<WarningLevel%s>Level3</WarningLevel>", condition)
+ elseif flagstr:find("[%-/]W4") then
+ vcxprojfile:print("<WarningLevel%s>Level4</WarningLevel>", condition)
elseif flagstr:find("[%-/]Wall") then
vcxprojfile:print("<WarningLevel%s>EnableAllWarnings</WarningLevel>", condition)
else
@@ -291,6 +309,35 @@ function _make_source_options(vcxprojfile, flags, condition)
vcxprojfile:print("<TreatWarningAsError%s>true</TreatWarningAsError>", condition)
end
+ -- make ExternalWarningLevel
+ if flagstr:find("[%-/]external:W1") then
+ vcxprojfile:print("<ExternalWarningLevel%s>Level1</ExternalWarningLevel>", condition)
+ elseif flagstr:find("[%-/]external:W2") then
+ vcxprojfile:print("<ExternalWarningLevel%s>Level2</ExternalWarningLevel>", condition)
+ elseif flagstr:find("[%-/]external:W3") then
+ vcxprojfile:print("<ExternalWarningLevel%s>Level3</ExternalWarningLevel>", condition)
+ elseif flagstr:find("[%-/]external:W4") then
+ vcxprojfile:print("<ExternalWarningLevel%s>Level4</ExternalWarningLevel>", condition)
+ else
+ vcxprojfile:print("<ExternalWarningLevel%s>TurnOffAllWarnings</ExternalWarningLevel>", condition)
+ end
+
+ -- make ExternalTemplatesDiagnostics
+ if flagstr:find("[%-/]external:templates-") then
+ vcxprojfile:print("<ExternalTemplatesDiagnostics%s>true</ExternalTemplatesDiagnostics>", condition)
+ else
+ vcxprojfile:print("<ExternalTemplatesDiagnostics%s>false</ExternalTemplatesDiagnostics>", condition)
+ end
+
+ -- make DisableSpecificWarnings
+ local disabledwarnings = {}
+ for _, flag in ipairs(flags) do
+ flag:gsub("[%-/]wd(%d+)", function (warn) table.insert(disabledwarnings, warn) end)
+ end
+ if #disabledwarnings > 0 then
+ vcxprojfile:print("<DisableSpecificWarnings>%s;%%(DisableSpecificWarnings)</DisableSpecificWarnings>", table.concat(disabledwarnings, ";"))
+ end
+
-- make PreprocessorDefinitions
local defstr = ""
for _, flag in ipairs(flags) do
@@ -328,7 +375,7 @@ function _make_source_options(vcxprojfile, flags, condition)
-- handle multi processor compilation
if flagstr:find("[%-/]Gm-") or not flagstr:find("[%-/]Gm") then
vcxprojfile:print("<MinimalRebuild%s>false</MinimalRebuild>", condition)
- if flagstr:find("[%-/]MP") then
+ if not flagstr:find("[%-/]MP1") then
vcxprojfile:print("<MultiProcessorCompilation%s>true</MultiProcessorCompilation>", condition)
end
end
@@ -351,7 +398,11 @@ function _make_source_options(vcxprojfile, flags, condition)
-- make AdditionalOptions
local additional_flags = {}
- local excludes = {"Od", "Os", "O0", "O1", "O2", "Ot", "Ox", "W0", "W1", "W2", "W3", "WX", "Wall", "Zi", "ZI", "Z7", "MT", "MTd", "MD", "MDd", "TP", "Fd", "fp", "I", "D", "Gm-", "Gm"}
+ local excludes = {
+ "Od", "Os", "O0", "O1", "O2", "Ot", "Ox", "W0", "W1", "W2", "W3", "W4", "WX", "Wall", "Zi", "ZI", "Z7", "MT", "MTd", "MD", "MDd", "TP",
+ "Fd", "fp", "I", "D", "Gm-", "Gm", "MP", "external:W0", "external:W1", "external:W2", "external:W3", "external:W4", "external:templates-?", "external:I",
+ "std:c11", "std:c17", "std:c%+%+11", "std:c%+%+14", "std:c%+%+17", "std:c%+%+20", "std:c%+%+latest", "nologo", "wd(%d+)"
+ }
for _, flag in ipairs(flags) do
local excluded = false
for _, exclude in ipairs(excludes) do
@@ -369,8 +420,46 @@ function _make_source_options(vcxprojfile, flags, condition)
end
end
+-- make custom commands item
+function _make_custom_commands_item(vcxprojfile, commands, suffix)
+ if suffix == "after" or suffix == "after_link" then
+ vcxprojfile:print("<PostBuildEvent>")
+ elseif suffix == "before" then
+ vcxprojfile:print("<PreBuildEvent>")
+ elseif suffix == "before_link" then
+ vcxprojfile:print("<PreLinkEvent>")
+ end
+ vcxprojfile:print("<Message></Message>")
+ vcxprojfile:print("<Command>setlocal")
+ for _, command in ipairs(commands) do
+ vcxprojfile:print("%s", command)
+ end
+ vcxprojfile:write([[if %errorlevel% neq 0 goto :xmEnd
+:xmEnd
+endlocal &amp; call :xmErrorLevel %errorlevel% &amp; goto :xmDone
+:xmErrorLevel
+exit /b %1
+:xmDone
+if %errorlevel% neq 0 goto :VCEnd</Command>
+]])
+ if suffix == "after" or suffix == "after_link" then
+ vcxprojfile:print("</PostBuildEvent>")
+ elseif suffix == "before" then
+ vcxprojfile:print("</PreBuildEvent>")
+ elseif suffix == "before_link" then
+ vcxprojfile:print("</PreLinkEvent>")
+ end
+end
+
+-- make custom commands
+function _make_custom_commands(vcxprojfile, target)
+ for suffix, cmds in pairs(target.commands) do
+ _make_custom_commands_item(vcxprojfile, cmds, suffix)
+ end
+end
+
-- make common item
-function _make_common_item(vcxprojfile, vsinfo, target, targetinfo, vcxprojdir)
+function _make_common_item(vcxprojfile, vsinfo, target, targetinfo)
-- enter ItemDefinitionGroup
vcxprojfile:enter("<ItemDefinitionGroup Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">", targetinfo.mode, targetinfo.arch)
@@ -391,22 +480,54 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo, vcxprojdir)
-- make linker flags
local flags = {}
- for _, flag in ipairs(_make_linkflags(targetinfo, vcxprojdir)) do
+ local excludes = {
+ "nologo", "machine:%w+", "pdb:.+%.pdb", "debug"
+ }
+ local libdirs = {}
+ local links = {}
+ for _, flag in ipairs(_make_linkflags(targetinfo, target.project_dir)) do
local flag_lower = flag:lower()
-- remove "-subsystem:windows"
if flag_lower:find("[%-/]subsystem:windows") then
subsystem = "Windows"
- -- remove "-machine:[x86|x64]", "-pdb:*.pdb" and "-debug"
- elseif not flag_lower:find("[%-/]machine:%w+") and not flag_lower:find("[%-/]pdb:.+%.pdb") and not flag_lower:find("[%-/]debug") then
- table.insert(flags, flag)
+ elseif flag_lower:find("[%-/]libpath") then
+ -- link dir
+ flag:gsub("[%-/]libpath:(.*)", function (dir) table.insert(libdirs, dir) end)
+ elseif flag_lower:find("[^%-/].+%.lib") then
+ -- link file
+ table.insert(links, flag)
+ else
+ local excluded = false
+ for _, exclude in ipairs(excludes) do
+ if flag:find("[%-/]" .. exclude) then
+ excluded = true
+ break
+ end
+ end
+ if not excluded then
+ table.insert(flags, flag)
+ end
end
+
+ end
+
+ -- make AdditionalLibraryDirectories
+ if #libdirs > 0 then
+ vcxprojfile:print("<AdditionalLibraryDirectories>%s;%%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>", table.concat(libdirs, ";"))
+ end
+
+ -- make AdditionalDependencies
+ if #links > 0 then
+ vcxprojfile:print("<AdditionalDependencies>%s;%%(AdditionalDependencies)</AdditionalDependencies>", table.concat(links, ";"))
end
- flags = os.args(flags)
-- make AdditionalOptions
- vcxprojfile:print("<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>", flags)
+ if #flags > 0 then
+ flags = os.args(flags)
+ vcxprojfile:print("<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>", flags)
+ end
-- generate debug infomation?
if linkerkinds[targetinfo.targetkind] == "Link" then
@@ -439,6 +560,49 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo, vcxprojdir)
-- make source options
_make_source_options(vcxprojfile, targetinfo.commonflags)
+ -- add c and c++ standard
+ local clangflags = {
+ c11 = "stdc11",
+ c17 = "stdc17",
+ clatest = "stdc17",
+ gnu11 = "stdc11",
+ gnu17 = "stdc17",
+ gnulatest = "stdc17",
+ }
+
+ local cxxlangflags = {
+ cxx11 = "stdcpp11",
+ cxx14 = "stdcpp14",
+ cxx17 = "stdcpp17",
+ cxx1z = "stdcpp17",
+ cxx20 = "stdcpp20",
+ cxx2a = "stdcpplatest",
+ cxxlatest = "stdcpplatest",
+ gnuxx11 = "stdcpp11",
+ gnuxx14 = "stdcpp14",
+ gnuxx17 = "stdcpp17",
+ gnuxx1z = "stdcpp20",
+ gnux20 = "stdcpp20",
+ gnux2a = "stdcpplatest",
+ }
+
+ local cstandard
+ local cxxstandard
+ for _, lang in pairs(targetinfo.languages) do
+ if cxxlangflags[lang] then
+ cxxstandard = cxxlangflags[lang]
+ elseif clangflags[lang] then
+ cstandard = clangflags[lang]
+ end
+ end
+
+ if cxxstandard then
+ vcxprojfile:print("<LanguageStandard>%s</LanguageStandard>", cxxstandard)
+ end
+
+ if cstandard then
+ vcxprojfile:print("<LanguageStandard_C>%s</LanguageStandard_C>", cstandard)
+ end
-- use c or c++ precompiled header
local pcheader = target.pcxxheader or target.pcheader
@@ -449,19 +613,22 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo, vcxprojdir)
vcxprojfile:print("<PrecompiledHeaderFile>%s</PrecompiledHeaderFile>", path.filename(pcheader))
local pcoutputfile = targetinfo.pcxxoutputfile or targetinfo.pcoutputfile
if pcoutputfile then
- vcxprojfile:print("<PrecompiledHeaderOutputFile>%s</PrecompiledHeaderOutputFile>", path.relative(path.absolute(pcoutputfile), vcxprojdir))
+ vcxprojfile:print("<PrecompiledHeaderOutputFile>%s</PrecompiledHeaderOutputFile>", path.relative(path.absolute(pcoutputfile), target.project_dir))
end
vcxprojfile:print("<ForcedIncludeFiles>%s;%%(ForcedIncludeFiles)</ForcedIncludeFiles>", path.filename(pcheader))
end
vcxprojfile:leave("</ClCompile>")
+ -- make custom commands
+ _make_custom_commands(vcxprojfile, targetinfo)
+
-- leave ItemDefinitionGroup
vcxprojfile:leave("</ItemDefinitionGroup>")
end
--- make common items
-function _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir)
+-- build common items (doesn't print anything)
+function _build_common_items(vsinfo, target)
-- for each mode and arch
for _, targetinfo in ipairs(target.info) do
@@ -477,7 +644,7 @@ function _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir)
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
-- make compiler flags
- local flags = _make_compflags(sourcefile, targetinfo, vcxprojdir)
+ local flags = _make_compflags(sourcefile, targetinfo, target.project_dir)
-- no common flags for asm
if sourcekind ~= "as" then
@@ -503,7 +670,7 @@ function _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir)
-- make common flags
targetinfo.commonflags = {}
for _, flag in ipairs(first_flags) do
- if flags_stats[flag] == files_count then
+ if flags_stats[flag] >= files_count then
table.insert(targetinfo.commonflags, flag)
end
end
@@ -513,16 +680,23 @@ function _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir)
for sourcefile, flags in pairs(targetinfo.sourceflags) do
local otherflags = {}
for _, flag in ipairs(flags) do
- if flags_stats[flag] ~= files_count then
+ if flags_stats[flag] < files_count then
table.insert(otherflags, flag)
end
end
sourceflags[sourcefile] = otherflags
end
targetinfo.sourceflags = sourceflags
+ end
+end
+-- make common items
+function _make_common_items(vcxprojfile, vsinfo, target)
+
+ -- for each mode and arch
+ for _, targetinfo in ipairs(target.info) do
-- make common item
- _make_common_item(vcxprojfile, vsinfo, target, targetinfo, vcxprojdir)
+ _make_common_item(vcxprojfile, vsinfo, target, targetinfo, target.project_dir)
end
end
@@ -532,7 +706,7 @@ function _make_header_file(vcxprojfile, includefile, vcxprojdir)
end
-- make source file for all modes
-function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
+function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourceinfo)
-- get object file and source kind
local sourcekind = nil
@@ -543,7 +717,7 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
-- enter it
local nodename = (sourcekind == "as" and "CustomBuild" or (sourcekind == "mrc" and "ResourceCompile" or "ClCompile"))
- sourcefile = path.relative(path.absolute(sourcefile), vcxprojdir)
+ sourcefile = path.relative(path.absolute(sourcefile), target.project_dir)
vcxprojfile:enter("<%s Include=\"%s\">", nodename, sourcefile)
-- for *.asm files
@@ -551,8 +725,8 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
vcxprojfile:print("<ExcludedFromBuild>false</ExcludedFromBuild>")
vcxprojfile:print("<FileType>Document</FileType>")
for _, info in ipairs(sourceinfo) do
- local objectfile = path.relative(path.absolute(info.objectfile), vcxprojdir)
- local compcmd = _make_compcmd(info.compargv, sourcefile, objectfile, vcxprojdir)
+ local objectfile = path.relative(path.absolute(info.objectfile), target.project_dir)
+ local compcmd = _make_compcmd(info.compargv, sourcefile, objectfile, target.project_dir)
vcxprojfile:print("<Outputs Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s\'\">%s</Outputs>", info.mode .. '|' .. info.arch, objectfile)
vcxprojfile:print("<Command Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s\'\">%s</Command>", info.mode .. '|' .. info.arch, compcmd)
end
@@ -561,7 +735,7 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
-- for *.rc files
elseif sourcekind == "mrc" then
for _, info in ipairs(sourceinfo) do
- local objectfile = path.relative(path.absolute(info.objectfile), vcxprojdir)
+ local objectfile = path.relative(path.absolute(info.objectfile), target.project_dir)
vcxprojfile:print("<ResourceOutputFileName Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">%s</ResourceOutputFileName>", info.mode, info.arch, objectfile)
end
@@ -648,10 +822,10 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
end
-- make source file for specific modes
-function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
+function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sourceinfo)
-- add source file
- sourcefile = path.relative(path.absolute(sourcefile), vcxprojdir)
+ sourcefile = path.relative(path.absolute(sourcefile), target.project_dir)
for _, info in ipairs(sourceinfo) do
-- enter it
@@ -659,9 +833,9 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
vcxprojfile:enter("<%s Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\" Include=\"%s\">", nodename, info.mode, info.arch, sourcefile)
-- for *.asm files
- local objectfile = path.relative(path.absolute(info.objectfile), vcxprojdir)
+ local objectfile = path.relative(path.absolute(info.objectfile), target.project_dir)
if info.sourcekind == "as" then
- local compcmd = _make_compcmd(info.compargv, sourcefile, objectfile, vcxprojdir)
+ local compcmd = _make_compcmd(info.compargv, sourcefile, objectfile, target.project_dir)
vcxprojfile:print("<ExcludedFromBuild>false</ExcludedFromBuild>")
vcxprojfile:print("<FileType>Document</FileType>")
vcxprojfile:print("<Outputs>%s</Outputs>", objectfile)
@@ -688,12 +862,12 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
end
-- make source file for precompiled header
-function _make_source_file_forpch(vcxprojfile, vsinfo, target, vcxprojdir)
+function _make_source_file_forpch(vcxprojfile, vsinfo, target)
-- add precompiled source file
local pcheader = target.pcxxheader or target.pcheader
if pcheader then
- local sourcefile = path.relative(path.absolute(pcheader), vcxprojdir)
+ local sourcefile = path.relative(path.absolute(pcheader), target.project_dir)
vcxprojfile:enter("<ClCompile Include=\"%s\">", sourcefile)
vcxprojfile:print("<PrecompiledHeader>Create</PrecompiledHeader>")
vcxprojfile:print("<PrecompiledHeaderFile></PrecompiledHeaderFile>")
@@ -707,7 +881,7 @@ function _make_source_file_forpch(vcxprojfile, vsinfo, target, vcxprojdir)
-- add object file
local pcoutputfile = info.pcxxoutputfile or info.pcoutputfile
if pcoutputfile then
- local objectfile = path.relative(path.absolute(pcoutputfile .. ".obj"), vcxprojdir)
+ local objectfile = path.relative(path.absolute(pcoutputfile .. ".obj"), target.project_dir)
vcxprojfile:print("<ObjectFileName Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">%s</ObjectFileName>", info.mode, info.arch, objectfile)
end
end
@@ -716,7 +890,7 @@ function _make_source_file_forpch(vcxprojfile, vsinfo, target, vcxprojdir)
end
-- make source files
-function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir)
+function _make_source_files(vcxprojfile, vsinfo, target)
-- add source files
vcxprojfile:enter("<ItemGroup>")
@@ -741,14 +915,14 @@ function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir)
-- make source files
for sourcefile, sourceinfo in pairs(sourceinfos) do
if #sourceinfo == #target.info then
- _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
+ _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourceinfo)
else
- _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
+ _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sourceinfo)
end
end
-- make precompiled source file
- _make_source_file_forpch(vcxprojfile, vsinfo, target, vcxprojdir)
+ _make_source_file_forpch(vcxprojfile, vsinfo, target)
vcxprojfile:leave("</ItemGroup>")
@@ -758,7 +932,7 @@ function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir)
for _, includefile in ipairs(target.headerfiles) do
-- we need ignore pcheader file to fix https://github.com/xmake-io/xmake/issues/1171
if not pcheader or includefile ~= pcheader then
- _make_header_file(vcxprojfile, includefile, vcxprojdir)
+ _make_header_file(vcxprojfile, includefile, target.project_dir)
end
end
vcxprojfile:leave("</ItemGroup>")
@@ -771,7 +945,10 @@ function make(vsinfo, target)
local targetname = target.name
-- the vcxproj directory
- local vcxprojdir = path.join(vsinfo.solution_dir, targetname)
+ local vcxprojdir = target.project_dir
+
+ -- build common flags
+ _build_common_items(vsinfo, target)
-- open vcxproj file
local vcxprojpath = path.join(vcxprojdir, targetname .. ".vcxproj")
@@ -784,13 +961,13 @@ function make(vsinfo, target)
_make_header(vcxprojfile, vsinfo)
-- make Configurations
- _make_configurations(vcxprojfile, vsinfo, target, vcxprojdir)
+ _make_configurations(vcxprojfile, vsinfo, target)
-- make common items
- _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir)
+ _make_common_items(vcxprojfile, vsinfo, target)
-- make source files
- _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir)
+ _make_source_files(vcxprojfile, vsinfo, target)
-- make tailer
_make_tailer(vcxprojfile, vsinfo)
diff --git a/xmake/plugins/project/vstudio/impl/vsfile.lua b/xmake/plugins/project/vstudio/impl/vsfile.lua
index a17384716..040bbee2b 100644
--- a/xmake/plugins/project/vstudio/impl/vsfile.lua
+++ b/xmake/plugins/project/vstudio/impl/vsfile.lua
@@ -97,7 +97,7 @@ end
function open(filepath, mode)
-- open it
- local file = io.open(filepath, mode)
+ local file = io.open(filepath, mode, {encoding = "utf8bom"})
-- hook print, printf and write
file._print_impl = file.print
diff --git a/xmake/plugins/project/vstudio/impl/vsinfo.lua b/xmake/plugins/project/vstudio/impl/vsinfo.lua
index 9b6cc829c..e210f6705 100644
--- a/xmake/plugins/project/vstudio/impl/vsinfo.lua
+++ b/xmake/plugins/project/vstudio/impl/vsinfo.lua
@@ -90,7 +90,7 @@ local vsinfo =
, project_version = "17"
, filters_version = "4.0"
, solution_version = "12"
- , toolset_version = "v142"
+ , toolset_version = "v143"
, sdk_version = "10.0.19041.0"
}
}
diff --git a/xmake/plugins/project/vsxmake/render.lua b/xmake/plugins/project/vsxmake/render.lua
index 99be35197..d599f1dde 100644
--- a/xmake/plugins/project/vsxmake/render.lua
+++ b/xmake/plugins/project/vsxmake/render.lua
@@ -18,7 +18,7 @@
-- @file render.lua
--
-function _fill(opt, parmas)
+function _fill(opt, params)
return function(match)
local imp = match:match("^Import%((.+)%)$")
if imp then
@@ -28,7 +28,7 @@ function _fill(opt, parmas)
local args = path.filename(func):match("%((.+)%)$"):split(",")
return _render(func, opt, args)
end
- return opt.paramsprovider(match, parmas) or "<Not Provided>"
+ return opt.paramsprovider(match, params) or "<Not Provided>"
end
end
diff --git a/xmake/plugins/project/vsxmake/vsproj/Xmake.props b/xmake/plugins/project/vsxmake/vsproj/Xmake.props
index a783c8ebc..8b4b721d0 100644
--- a/xmake/plugins/project/vsxmake/vsproj/Xmake.props
+++ b/xmake/plugins/project/vsxmake/vsproj/Xmake.props
@@ -58,6 +58,7 @@
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
+ <PlatformToolset Condition="'$(VisualStudioVersion)' == '17.0'">v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="AdditionalProps">
@@ -94,6 +95,7 @@
<LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('cxx1z'))">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('cxx20'))">stdcpplatest</LanguageStandard>
<LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('cxx2a'))">stdcpplatest</LanguageStandard>
+ <LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('cxxlatest'))">stdcpplatest</LanguageStandard>
<LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('gnuxx11'))">stdcpp11</LanguageStandard>
<LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('gnuxx14'))">stdcpp14</LanguageStandard>
<LanguageStandard Condition="'%(LanguageStandard)' == '' And $(XmakeLanguages.Contains('gnuxx17'))">stdcpp17</LanguageStandard>
diff --git a/xmake/plugins/project/vsxmake/vsproj/Xmake.targets b/xmake/plugins/project/vsxmake/vsproj/Xmake.targets
index 9a23799c1..ce78b88e9 100644
--- a/xmake/plugins/project/vsxmake/vsproj/Xmake.targets
+++ b/xmake/plugins/project/vsxmake/vsproj/Xmake.targets
@@ -65,7 +65,6 @@
<_XmakeExecutable>"$([System.IO.Path]::GetFullPath('$(XmakeProgramDirResolved)xmake.exe'))"</_XmakeExecutable>
<_XmakeEnv>
- chcp 65001 &gt; NUL
pushd $(XmakeProjectDirResolved)
set XMAKE_CONFIGDIR=$(XmakeConfigDirResolved.TrimEnd('\').TrimEnd('/'))
set XMAKE_PROGRAM_DIR=$(XmakeProgramDirResolved.TrimEnd('\').TrimEnd('/'))
@@ -77,7 +76,6 @@
echo XMAKE_CONFIGDIR=%25XMAKE_CONFIGDIR%25
echo XMAKE_PROGRAM_DIR=%25XMAKE_PROGRAM_DIR%25
echo CD=%25CD%25
- chcp
</_XmakeEnv>
</PropertyGroup>
diff --git a/xmake/plugins/project/vsxmake/vsxmake.lua b/xmake/plugins/project/vsxmake/vsxmake.lua
index 0055aaff2..469448764 100644
--- a/xmake/plugins/project/vsxmake/vsxmake.lua
+++ b/xmake/plugins/project/vsxmake/vsxmake.lua
@@ -19,6 +19,7 @@
--
-- imports
+import("core.base.option")
import("core.base.hashset")
import("vstudio.impl.vsinfo", { rootdir = path.directory(os.scriptdir()) })
import("render")
@@ -167,9 +168,22 @@ function _writefileifneeded(file, content)
dprint("skipped file %s since the file has the same content", path.relative(file))
return
end
- io.writefile(file, content)
+ -- we need utf8 with bom encoding for unicode
+ -- @see https://github.com/xmake-io/xmake/issues/1689
+ io.writefile(file, content, {encoding = "utf8bom"})
end
+-- save plugin arguments for `plugin.vsxmake.autoupdate`
+-- @see https://github.com/xmake-io/xmake/issues/1895
+function _save_plugin_arguments()
+ local vsxmake_cache = localcache.cache("vsxmake")
+ for _, name in ipairs({"kind", "modes", "archs", "outputdir"}) do
+ vsxmake_cache:set(name, option.get(name))
+ end
+ vsxmake_cache:save()
+end
+
+-- clear configuration cache
function _clear_cacheconf()
config.clear()
config.save()
@@ -188,7 +202,7 @@ function make(version)
version = tonumber(config.get("vs"))
if not version then
return function(outputdir)
- raise("invalid vs version, run `xmake f --vs=201x`")
+ raise("invalid vs version, run `xmake f --vs=20xx`")
end
end
end
@@ -233,5 +247,8 @@ function make(version)
-- clear config and local cache
_clear_cacheconf()
+
+ -- save plugin arguments for autoupdate
+ _save_plugin_arguments()
end
end
diff --git a/xmake/plugins/repo/main.lua b/xmake/plugins/repo/main.lua
index a4ec01b90..4baa1f540 100644
--- a/xmake/plugins/repo/main.lua
+++ b/xmake/plugins/repo/main.lua
@@ -25,6 +25,7 @@ import("core.project.project")
import("core.platform.platform")
import("core.package.repository")
import("devel.git")
+import("net.proxy")
import("private.async.runjobs")
import("private.action.require.impl.environment")
@@ -45,7 +46,8 @@ function _add(name, url, branch, is_global)
-- clone repository
if not os.isdir(url) then
- git.clone(url, {verbose = option.get("verbose"), branch = branch or "master", outputdir = repodir})
+ local remoteurl = proxy.mirror(url) or url
+ git.clone(remoteurl, {verbose = option.get("verbose"), branch = branch or "master", outputdir = repodir})
end
-- trace
@@ -117,7 +119,8 @@ function _update()
vprint("cloning repository(%s): %s to %s ..", repo:name(), repo:url(), repodir)
-- clone it
- git.clone(repo:url(), {verbose = option.get("verbose"), branch = repo:branch() or "master", outputdir = repodir})
+ local remoteurl = proxy.mirror(repo:url()) or repo:url()
+ git.clone(remoteurl, {verbose = option.get("verbose"), branch = repo:branch() or "master", outputdir = repodir})
-- mark as updated
io.save(path.join(repodir, "updated"), {})
diff --git a/xmake/plugins/show/info/target.lua b/xmake/plugins/show/info/target.lua
index fb99b31e4..7d86329ef 100644
--- a/xmake/plugins/show/info/target.lua
+++ b/xmake/plugins/show/info/target.lua
@@ -72,8 +72,12 @@ function main(name)
cprint(" ${color.dump.string}sourcebatch${clear}(%s): with rule(%s)", sourcebatch.sourcekind, sourcebatch.rulename)
for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do
cprint(" -> %s", sourcefile)
- cprint(" ${dim}-> %s", sourcebatch.objectfiles[idx])
- cprint(" ${dim}-> %s", sourcebatch.dependfiles[idx])
+ if sourcebatch.objectfiles then
+ cprint(" ${dim}-> %s", sourcebatch.objectfiles[idx])
+ end
+ if sourcebatch.dependfiles then
+ cprint(" ${dim}-> %s", sourcebatch.dependfiles[idx])
+ end
end
end
end
diff --git a/xmake/plugins/show/lists/architectures.lua b/xmake/plugins/show/lists/architectures.lua
new file mode 100644
index 000000000..8eba152f2
--- /dev/null
+++ b/xmake/plugins/show/lists/architectures.lua
@@ -0,0 +1,51 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file platforms.lua
+--
+
+-- imports
+import("core.project.project")
+import("core.platform.platform")
+import("core.base.text")
+
+-- show all platforms
+function main()
+
+ -- get all platforms
+ local plats = try {function () return project.allowed_plats() end}
+ if plats then
+ plats = plats:to_array()
+ end
+ plats = plats or platform.plats()
+
+ -- get all architectures
+ local result = {align = 'l', sep = " "}
+ for i, plat in ipairs(plats) do
+ local archs = try {function () return project.allowed_archs(plat) end}
+ if archs then
+ archs = archs:to_array()
+ end
+ if not archs then
+ archs = platform.archs(plat)
+ end
+ if archs and #archs > 0 then
+ table.insert(result, table.join(plat, archs))
+ end
+ end
+ print(text.table(result))
+end
diff --git a/xmake/plugins/show/showlist.lua b/xmake/plugins/show/showlist.lua
index 66090fc48..923228e42 100644
--- a/xmake/plugins/show/showlist.lua
+++ b/xmake/plugins/show/showlist.lua
@@ -28,7 +28,7 @@ function main(values)
local row = {}
for _, value in ipairs(values) do
table.insert(row, value)
- if #row > 5 then
+ if #row > 2 then
table.insert(tbl, row)
row = {}
end
diff --git a/xmake/rules/c++/modules/build_modulefiles.lua b/xmake/rules/c++/modules/build_modulefiles.lua
deleted file mode 100644
index 75593f0cc..000000000
--- a/xmake/rules/c++/modules/build_modulefiles.lua
+++ /dev/null
@@ -1,151 +0,0 @@
---!A cross-platform build utility based on Lua
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
--- Copyright (C) 2015-present, TBOOX Open Source Group.
---
--- @author ruki
--- @file build_modulefiles.lua
---
-
--- imports
-import("core.tool.compiler")
-
--- build module files using clang
-function _build_modulefiles_clang(target, sourcebatch, opt)
-
- -- attempt to compile the module files as cxx
- sourcebatch.sourcekind = "cxx"
- sourcebatch.objectfiles = sourcebatch.objectfiles or {}
- sourcebatch.dependfiles = sourcebatch.dependfiles or {}
- for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
- local objectfile = target:objectfile(sourcefile) .. ".pcm"
- table.insert(sourcebatch.objectfiles, objectfile)
- table.insert(sourcebatch.dependfiles, target:dependfile(objectfile))
- end
-
- -- compile module files to *.pcm
- opt = table.join(opt, {configs = {force = {cxxflags = {opt.modulesflag, "--precompile", "-x c++-module"}}}})
- import("private.action.build.object").build(target, sourcebatch, opt)
-
- -- compile *.pcm to object files
- local modulefiles = {}
- for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do
- local modulefile = sourcebatch.objectfiles[idx]
- local objectfile = target:objectfile(sourcefile)
- sourcebatch.sourcefiles[idx] = modulefile
- sourcebatch.objectfiles[idx] = objectfile
- sourcebatch.dependfiles[idx] = target:dependfile(objectfile)
- table.insert(modulefiles, modulefile)
- end
- opt.configs = {cxxflags = {opt.modulesflag}}
- opt.quiet = true
- import("private.action.build.object").build(target, sourcebatch, opt)
-
- -- add module files
- target:add("cxxflags", opt.modulesflag)
- for _, modulefile in ipairs(modulefiles) do
- target:add("cxxflags", "-fmodules", "-fimplicit-modules", "-fimplicit-module-maps", "-fmodule-file=" .. modulefile)
- end
-end
-
--- TODO
--- build module files using gcc
-function _build_modulefiles_gcc(target, sourcebatch, opt)
-
- -- attempt to compile the module files as cxx
- local modulefiles = {}
- opt = table.join(opt, {configs = {}})
- sourcebatch.sourcekind = "cxx"
- sourcebatch.objectfiles = sourcebatch.objectfiles or {}
- sourcebatch.dependfiles = sourcebatch.dependfiles or {}
- for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
- local objectfile = target:objectfile(sourcefile)
- local dependfile = target:dependfile(objectfile)
- local modulefile = objectfile .. ".pcm"
-
- -- compile module file to *.pcm
- local singlebatch = {sourcekind = "cxx", sourcefiles = {sourcefile}, objectfiles = {objectfile}, dependfiles = {dependfile}}
- opt.configs.cxxflags = {"-fmodules-ts", "-x c++"}
- import("private.action.build.object").build(target, singlebatch, opt)
- table.insert(modulefiles, modulefile)
- table.insert(sourcebatch.objectfiles, objectfile)
- table.insert(sourcebatch.dependfiles, dependfile)
- end
-
- -- add module files
- for _, modulefile in ipairs(modulefiles) do
- target:add("cxxflags", "-fmodules-ts", "-fmodule-file=" .. modulefile)
- end
-end
-
--- build module files using msvc
-function _build_modulefiles_msvc(target, sourcebatch, opt)
-
- -- attempt to compile the module files as cxx
- local modulefiles = {}
- opt = table.join(opt, {configs = {}})
- sourcebatch.sourcekind = "cxx"
- sourcebatch.objectfiles = sourcebatch.objectfiles or {}
- sourcebatch.dependfiles = sourcebatch.dependfiles or {}
- for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
- local objectfile = target:objectfile(sourcefile)
- local dependfile = target:dependfile(objectfile)
- local modulefile = objectfile .. ".pcm"
-
- -- compile module file to *.pcm
- local singlebatch = {sourcekind = "cxx", sourcefiles = {sourcefile}, objectfiles = {objectfile}, dependfiles = {dependfile}}
- opt.configs.cxxflags = {"/experimental:module /module:interface /module:output " .. os.args(modulefile), "/TP"}
- import("private.action.build.object").build(target, singlebatch, opt)
- table.insert(modulefiles, modulefile)
- table.insert(sourcebatch.objectfiles, objectfile)
- table.insert(sourcebatch.dependfiles, dependfile)
- end
-
- -- add module files
- for _, modulefile in ipairs(modulefiles) do
- target:add("cxxflags", "/experimental:module /module:reference " .. os.args(modulefile))
- end
-end
-
--- build module files
-function main(target, sourcebatch, opt)
-
- -- do compile
- local modulesflag = nil
- local toolname = target:tool("cxx")
- local compinst = compiler.load("cxx")
- if toolname:find("clang", 1, true) or toolname:find("gcc", 1, true) or toolname:find("g++", 1, true) then
- if compinst:has_flags("-fmodules") then
- modulesflag = "-fmodules"
- elseif compinst:has_flags("-fmodules-ts") then
- modulesflag = "-fmodules-ts"
- end
- elseif toolname == "cl" then
- if compinst:has_flags("/experimental:module") then
- modulesflag = "/experimental:module"
- end
- end
- if modulesflag then
- opt.modulesflag = modulesflag
- if toolname:find("clang", 1, true) then
- _build_modulefiles_clang(target, sourcebatch, opt)
- elseif toolname:find("gcc", 1, true) or toolname:find("g++", 1, true) then
- _build_modulefiles_gcc(target, sourcebatch, opt)
- elseif toolname == "cl" then
- _build_modulefiles_msvc(target, sourcebatch, opt)
- else
- raise("compiler(%s): does not support c++ module!", toolname)
- end
- end
-end
diff --git a/xmake/rules/c++/modules/build_modules/clang.lua b/xmake/rules/c++/modules/build_modules/clang.lua
new file mode 100644
index 000000000..523c61ad9
--- /dev/null
+++ b/xmake/rules/c++/modules/build_modules/clang.lua
@@ -0,0 +1,139 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file clang.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import("private.action.build.object", {alias = "objectbuilder"})
+import("module_parser")
+
+-- load parent target with modules files
+function load_parent(target, opt)
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("-fmodules") then
+ modulesflag = "-fmodules"
+ elseif compinst:has_flags("-fmodules-ts") then
+ modulesflag = "-fmodules-ts"
+ end
+ assert(modulesflag, "compiler(clang): does not support c++ module!")
+
+ -- add module flags
+ target:add("cxxflags", modulesflag)
+
+ -- the module cache directory
+ for _, dep in ipairs(target:orderdeps()) do
+ local sourcebatches = dep:sourcebatches()
+ if sourcebatches and sourcebatches["c++.build.modules"] then
+ local cachedir = path.join(dep:autogendir(), "rules", "modules", "cache")
+ target:add("cxxflags", "-fmodules-cache-path=" .. cachedir, {force = true})
+ target:add("cxxflags", "-fimplicit-modules", "-fimplicit-module-maps", "-fprebuilt-module-path=" .. cachedir, {force = true})
+ end
+ end
+end
+
+-- build module files
+function build_with_batchjobs(target, batchjobs, sourcebatch, opt)
+
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("-fmodules") then
+ modulesflag = "-fmodules"
+ elseif compinst:has_flags("-fmodules-ts") then
+ modulesflag = "-fmodules-ts"
+ end
+ assert(modulesflag, "compiler(clang): does not support c++ module!")
+
+ -- the module cache directory
+ local cachedir = path.join(target:autogendir(), "rules", "modules", "cache")
+
+ -- we need patch objectfiles to sourcebatch for linking module objects
+ local modulefiles = {}
+ sourcebatch.sourcekind = "cxx"
+ sourcebatch.objectfiles = sourcebatch.objectfiles or {}
+ sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local modulefile = path.join(cachedir, path.basename(sourcefile) .. ".pcm")
+ local objectfile = target:objectfile(sourcefile)
+ table.insert(sourcebatch.objectfiles, objectfile)
+ table.insert(sourcebatch.dependfiles, target:dependfile(objectfile))
+ table.insert(modulefiles, modulefile)
+ end
+
+ -- load moduledeps
+ local moduledeps = module_parser.load(target, sourcebatch, opt)
+
+ -- build moduledeps
+ local moduledeps_files = module_parser.build(moduledeps)
+
+ -- compile module files to object files
+ local count = 0
+ local sourcefiles_total = #sourcebatch.sourcefiles
+ for i = 1, sourcefiles_total do
+ local sourcefile = sourcebatch.sourcefiles[i]
+ local moduledep = assert(moduledeps_files[sourcefile], "moduledep(%s) not found!", sourcefile)
+ moduledep.job = batchjobs:newjob(sourcefile, function (index, total)
+
+ -- compile module files to *.pcm
+ local opt2 = table.join(opt, {configs = {force = {cxxflags = {modulesflag,
+ "-fimplicit-modules", "-fimplicit-module-maps", "-fprebuilt-module-path=" .. cachedir,
+ "--precompile", "-x c++-module", "-fmodules-cache-path=" .. cachedir}}}})
+ opt2.progress = (index * 100) / total
+ opt2.objectfile = modulefiles[i]
+ opt2.dependfile = target:dependfile(opt2.objectfile)
+ opt2.sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile)
+ objectbuilder.build_object(target, sourcefile, opt2)
+
+ -- compile *.pcm to object files
+ opt2.configs = {force = {cxxflags = {modulesflag, "-fmodules-cache-path=" .. cachedir,
+ "-fimplicit-modules", "-fimplicit-module-maps", "-fprebuilt-module-path=" .. cachedir}}}
+ opt2.quiet = true
+ opt2.objectfile = sourcebatch.objectfiles[i]
+ opt2.dependfile = sourcebatch.dependfiles[i]
+ objectbuilder.build_object(target, modulefiles[i], opt2)
+
+ -- add module flags to other c++ files after building all modules
+ count = count + 1
+ if count == sourcefiles_total then
+ target:add("cxxflags", modulesflag, "-fmodules-cache-path=" .. cachedir, {force = true})
+ -- FIXME It is invalid for the module implementation unit
+ --target:add("cxxflags", "-fimplicit-modules", "-fimplicit-module-maps", "-fprebuilt-module-path=" .. cachedir, {force = true})
+ for _, modulefile in ipairs(modulefiles) do
+ target:add("cxxflags", "-fmodule-file=" .. modulefile, {force = true})
+ end
+ end
+
+ end)
+ end
+
+ -- build batchjobs
+ local rootjob = opt.rootjob
+ for _, moduledep in pairs(moduledeps) do
+ if moduledep.parents then
+ for _, parent in ipairs(moduledep.parents) do
+ batchjobs:add(moduledep.job, parent.job)
+ end
+ else
+ batchjobs:add(moduledep.job, rootjob)
+ end
+ end
+end
+
diff --git a/xmake/rules/c++/modules/build_modules/gcc.lua b/xmake/rules/c++/modules/build_modules/gcc.lua
new file mode 100644
index 000000000..2abaa4f7f
--- /dev/null
+++ b/xmake/rules/c++/modules/build_modules/gcc.lua
@@ -0,0 +1,96 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file gcc.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import("private.action.build.object", {alias = "objectbuilder"})
+import("module_parser")
+
+-- load parent target with modules files
+function load_parent(target, opt)
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("-fmodules-ts") then
+ modulesflag = "-fmodules-ts"
+ end
+ assert(modulesflag, "compiler(gcc): does not support c++ module!")
+
+ -- add module flags
+ target:add("cxxflags", modulesflag)
+end
+
+-- build module files
+function build_with_batchjobs(target, batchjobs, sourcebatch, opt)
+
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("-fmodules-ts") then
+ modulesflag = "-fmodules-ts"
+ end
+ assert(modulesflag, "compiler(gcc): does not support c++ module!")
+
+ -- we need patch objectfiles to sourcebatch for linking module objects
+ sourcebatch.sourcekind = "cxx"
+ sourcebatch.objectfiles = sourcebatch.objectfiles or {}
+ sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local objectfile = target:objectfile(sourcefile)
+ table.insert(sourcebatch.objectfiles, objectfile)
+ table.insert(sourcebatch.dependfiles, target:dependfile(objectfile))
+ end
+
+ -- load moduledeps
+ local moduledeps = module_parser.load(target, sourcebatch, opt)
+
+ -- build moduledeps
+ local moduledeps_files = module_parser.build(moduledeps)
+
+ -- compile module files to object files
+ for i = 1, #sourcebatch.sourcefiles do
+ local sourcefile = sourcebatch.sourcefiles[i]
+ local moduledep = assert(moduledeps_files[sourcefile], "moduledep(%s) not found!", sourcefile)
+ moduledep.job = batchjobs:newjob(sourcefile, function (index, total)
+ local opt2 = table.join(opt, {configs = {force = {cxxflags = {"-x c++"}}}})
+ opt2.progress = (index * 100) / total
+ opt2.objectfile = sourcebatch.objectfiles[i]
+ opt2.dependfile = sourcebatch.dependfiles[i]
+ opt2.sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile)
+ objectbuilder.build_object(target, sourcefile, opt2)
+ end)
+ end
+
+ -- add module flags
+ target:add("cxxflags", modulesflag)
+
+ -- build batchjobs
+ local rootjob = opt.rootjob
+ for _, moduledep in pairs(moduledeps) do
+ if moduledep.parents then
+ for _, parent in ipairs(moduledep.parents) do
+ batchjobs:add(moduledep.job, parent.job)
+ end
+ else
+ batchjobs:add(moduledep.job, rootjob)
+ end
+ end
+end
+
diff --git a/xmake/rules/c++/modules/build_modules/module_parser.lua b/xmake/rules/c++/modules/build_modules/module_parser.lua
new file mode 100644
index 000000000..b97b7e1d0
--- /dev/null
+++ b/xmake/rules/c++/modules/build_modules/module_parser.lua
@@ -0,0 +1,118 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file module_parser.lua
+--
+
+-- imports
+import("core.project.depend")
+
+-- get depend file of module source file
+function _get_dependfile_of_modulesource(target, sourcefile)
+ return target:dependfile(sourcefile)
+end
+
+-- get depend file of module object file, compiler will rewrite it
+function _get_dependfile_of_moduleobject(target, sourcefile)
+ local objectfile = target:objectfile(sourcefile)
+ return target:dependfile(objectfile)
+end
+
+-- generate module deps for the given file
+function _generate_moduledeps(target, sourcefile, opt)
+ local dependfile = _get_dependfile_of_modulesource(target, sourcefile)
+ depend.on_changed(function ()
+
+ -- trace
+ vprint("generating.moduledeps %s", sourcefile)
+
+ -- generating deps
+ local module_name
+ local module_deps
+ local sourcecode = io.readfile(sourcefile)
+ sourcecode = sourcecode:gsub("//.-\n", "\n")
+ sourcecode = sourcecode:gsub("/%*.-%*/", "")
+ for _, line in ipairs(sourcecode:split("\n", {plain = true})) do
+ if not module_name then
+ module_name = line:match("export%s+module%s+(.+)%s*;")
+ end
+ local module_depname = line:match("import%s+(.+)%s*;")
+ if module_depname then
+ -- partition? import :xxx;
+ if module_depname:startswith(":") then
+ module_depname = module_name .. module_depname
+ end
+ module_deps = module_deps or {}
+ table.insert(module_deps, module_depname)
+ end
+ end
+
+ -- save depend data
+ if module_name then
+ local dependinfo = {moduleinfo = {name = module_name, deps = module_deps, file = sourcefile}}
+ return dependinfo
+ end
+
+ end, {dependfile = dependfile, files = {sourcefile}})
+end
+
+-- generate module deps
+function generate(target, sourcebatch, opt)
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ _generate_moduledeps(target, sourcefile, opt)
+ end
+end
+
+-- load module deps
+function load(target, sourcebatch, opt)
+
+ -- do generate first
+ generate(target, sourcebatch, opt)
+
+ -- load deps
+ local moduledeps
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local dependfile = _get_dependfile_of_modulesource(target, sourcefile)
+ if os.isfile(dependfile) then
+ local data = io.load(dependfile)
+ if data then
+ local moduleinfo = data.moduleinfo
+ moduledeps = moduledeps or {}
+ moduledeps[moduleinfo.name] = moduleinfo
+ end
+ end
+ end
+ return moduledeps
+end
+
+-- build module deps
+function build(moduledeps)
+ local moduledeps_files = {}
+ for _, moduledep in pairs(moduledeps) do
+ if moduledep.deps then
+ for _, depname in ipairs(moduledep.deps) do
+ local dep = moduledeps[depname]
+ if dep then
+ dep.parents = dep.parents or {}
+ table.insert(dep.parents, moduledep)
+ end
+ end
+ end
+ moduledeps_files[moduledep.file] = moduledep
+ end
+ return moduledeps_files
+end
diff --git a/xmake/rules/c++/modules/build_modules/msvc.lua b/xmake/rules/c++/modules/build_modules/msvc.lua
new file mode 100644
index 000000000..1dc04618f
--- /dev/null
+++ b/xmake/rules/c++/modules/build_modules/msvc.lua
@@ -0,0 +1,181 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file msvc.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import("private.action.build.object", {alias = "objectbuilder"})
+import("module_parser")
+
+-- load parent target with modules files
+function load_parent(target, opt)
+
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("/experimental:module", "cxxflags") then
+ modulesflag = "/experimental:module"
+ end
+ assert(modulesflag, "compiler(msvc): does not support c++ module!")
+
+ -- add module flags
+ target:add("cxxflags", modulesflag)
+
+ -- get output flag
+ if compinst:has_flags("/ifcOutput", "cxxflags") then
+ for _, dep in ipairs(target:orderdeps()) do
+ local sourcebatches = dep:sourcebatches()
+ if sourcebatches and sourcebatches["c++.build.modules"] then
+ local cachedir = path.join(dep:autogendir(), "rules", "modules", "cache")
+ target:add("cxxflags", "/ifcSearchDir " .. os.args(cachedir), {force = true})
+ end
+ end
+ end
+end
+
+-- build module files
+function build_with_batchjobs(target, batchjobs, sourcebatch, opt)
+
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("/experimental:module", "cxxflags") then
+ modulesflag = "/experimental:module"
+ end
+ assert(modulesflag, "compiler(msvc): does not support c++ module!")
+
+ -- get output flag
+ local cachedir
+ local outputflag
+ if compinst:has_flags("/ifcOutput", "cxxflags") then
+ outputflag = "/ifcOutput"
+ cachedir = path.join(target:autogendir(), "rules", "modules", "cache")
+ if not os.isdir(cachedir) then
+ os.mkdir(cachedir)
+ end
+ elseif compinst:has_flags("/module:output", "cxxflags") then
+ outputflag = "/module:output"
+ end
+ assert(outputflag, "compiler(msvc): does not support c++ module!")
+
+ -- get interface flag
+ local interfaceflag
+ if compinst:has_flags("/interface", "cxxflags") then
+ interfaceflag = "/interface"
+ elseif compinst:has_flags("/module:interface", "cxxflags") then
+ interfaceflag = "/module:interface"
+ end
+ assert(interfaceflag, "compiler(msvc): does not support c++ module!")
+
+ -- get reference flag
+ local referenceflag
+ if compinst:has_flags("/reference", "cxxflags") then
+ referenceflag = "/reference"
+ elseif compinst:has_flags("/module:interface", "cxxflags") then
+ referenceflag = "/module:reference"
+ end
+ assert(referenceflag, "compiler(msvc): does not support c++ module!")
+
+ -- get stdifcdir flag
+ local stdifcdirflag
+ if compinst:has_flags("/stdIfcDir", "cxxflags") then
+ stdifcdirflag = "/stdIfcDir"
+ elseif compinst:has_flags("/module:stdIfcDir", "cxxflags") then
+ stdifcdirflag = "/module:stdIfcDir"
+ end
+ assert(stdifcdirflag, "compiler(msvc): does not support c++ module!")
+
+ -- we need patch objectfiles to sourcebatch for linking module objects
+ local modulefiles = {}
+ sourcebatch.sourcekind = "cxx"
+ sourcebatch.objectfiles = sourcebatch.objectfiles or {}
+ sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local objectfile = target:objectfile(sourcefile)
+ local dependfile = target:dependfile(objectfile)
+ local modulefile = (cachedir and path.join(cachedir, path.basename(sourcefile)) or objectfile) .. ".ifc"
+ table.insert(modulefiles, modulefile)
+ table.insert(sourcebatch.objectfiles, objectfile)
+ table.insert(sourcebatch.dependfiles, dependfile)
+ end
+
+ -- load moduledeps
+ local moduledeps = module_parser.load(target, sourcebatch, opt)
+
+ -- build moduledeps
+ local moduledeps_files = module_parser.build(moduledeps)
+
+ -- compile module files to object files
+ local count = 0
+ local sourcefiles_total = #sourcebatch.sourcefiles
+ for i = 1, sourcefiles_total do
+ local sourcefile = sourcebatch.sourcefiles[i]
+ local moduledep = assert(moduledeps_files[sourcefile], "moduledep(%s) not found!", sourcefile)
+ moduledep.job = batchjobs:newjob(sourcefile, function (index, total)
+ local opt2 = table.join(opt, {configs = {force = {cxxflags = {interfaceflag,
+ outputflag .. " " .. os.args(modulefiles[i]), "/TP"}}}})
+ opt2.progress = (index * 100) / total
+ opt2.objectfile = sourcebatch.objectfiles[i]
+ opt2.dependfile = sourcebatch.dependfiles[i]
+ opt2.sourcekind = assert(sourcebatch.sourcekind, "%s: sourcekind not found!", sourcefile)
+ objectbuilder.build_object(target, sourcefile, opt2)
+
+ -- add module flags to other c++ files after building all modules
+ count = count + 1
+ if count == sourcefiles_total and not cachedir then
+ for _, modulefile in ipairs(modulefiles) do
+ target:add("cxxflags", referenceflag .. " " .. os.args(modulefile))
+ end
+ end
+ end)
+ end
+
+ -- add module flags
+ target:add("cxxflags", modulesflag)
+ if cachedir then
+ target:add("cxxflags", "/ifcSearchDir " .. os.args(cachedir))
+ end
+ if stdifcdirflag then
+ for _, toolchain_inst in ipairs(target:toolchains()) do
+ if toolchain_inst:name() == "msvc" then
+ local vcvars = toolchain_inst:config("vcvars")
+ if vcvars.VCInstallDir and vcvars.VCToolsVersion then
+ local stdifcdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "ifc", target:is_arch("x64") and "x64" or "x86")
+ if os.isdir(stdifcdir) then
+ target:add("cxxflags", stdifcdirflag .. " " .. winos.short_path(stdifcdir))
+ end
+ end
+ break
+ end
+ end
+ end
+
+ -- build batchjobs
+ local rootjob = opt.rootjob
+ for _, moduledep in pairs(moduledeps) do
+ if moduledep.parents then
+ for _, parent in ipairs(moduledep.parents) do
+ batchjobs:add(moduledep.job, parent.job)
+ end
+ else
+ batchjobs:add(moduledep.job, rootjob)
+ end
+ end
+end
+
diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua
index dfaf04897..c587a3912 100644
--- a/xmake/rules/c++/modules/xmake.lua
+++ b/xmake/rules/c++/modules/xmake.lua
@@ -21,5 +21,43 @@
-- define rule: c++.build.modules
rule("c++.build.modules")
set_extensions(".mpp", ".mxx", ".cppm", ".ixx")
- before_build_files("build_modulefiles")
+ on_config(function (target)
+ -- we disable to build across targets in parallel, because the source files may depend on other target modules
+ -- @see https://github.com/xmake-io/xmake/issues/1858
+ local target_with_modules
+ for _, dep in ipairs(target:orderdeps()) do
+ local sourcebatches = dep:sourcebatches()
+ if sourcebatches and sourcebatches["c++.build.modules"] then
+ target_with_modules = true
+ break
+ end
+ end
+ if target_with_modules then
+ -- @note this will cause cross-parallel builds to be disabled for all sub-dependent targets,
+ -- even if some sub-targets do not contain C++ modules.
+ --
+ -- maybe we will have a more fine-grained configuration strategy to disable it in the future.
+ target:set("policy", "build.across_targets_in_parallel", false)
+ if target:has_tool("cxx", "clang", "clangxx") then
+ import("build_modules.clang").load_parent(target, opt)
+ elseif target:has_tool("cxx", "gcc", "gxx") then
+ import("build_modules.gcc").load_parent(target, opt)
+ elseif target:has_tool("cxx", "cl") then
+ import("build_modules.msvc").load_parent(target, opt)
+ else
+ raise("compiler(%s): does not support c++ module!", toolname)
+ end
+ end
+ end)
+ before_build_files(function (target, batchjobs, sourcebatch, opt)
+ if target:has_tool("cxx", "clang", "clangxx") then
+ import("build_modules.clang").build_with_batchjobs(target, batchjobs, sourcebatch, opt)
+ elseif target:has_tool("cxx", "gcc", "gxx") then
+ import("build_modules.gcc").build_with_batchjobs(target, batchjobs, sourcebatch, opt)
+ elseif target:has_tool("cxx", "cl") then
+ import("build_modules.msvc").build_with_batchjobs(target, batchjobs, sourcebatch, opt)
+ else
+ raise("compiler(%s): does not support c++ module!", toolname)
+ end
+ end, {batch = true})
diff --git a/xmake/rules/c++/openmp/load.lua b/xmake/rules/c++/openmp/load.lua
index a4535f553..3f0508512 100644
--- a/xmake/rules/c++/openmp/load.lua
+++ b/xmake/rules/c++/openmp/load.lua
@@ -20,6 +20,7 @@
-- main entry
function main(target, sourcekind)
+ wprint("we no longer need add_rules(\"%s.openmp\") now, you just need to add add_packages(\"openmp\").", sourcekind == "cxx" and "c++" or "c")
local _, compiler_name = target:tool(sourcekind)
local flag_name = sourcekind == "cxx" and "cxxflags" or "cflags"
if compiler_name == "cl" then
diff --git a/xmake/rules/c++/openmp/xmake.lua b/xmake/rules/c++/openmp/xmake.lua
index 47dd2d07f..82e3cc562 100644
--- a/xmake/rules/c++/openmp/xmake.lua
+++ b/xmake/rules/c++/openmp/xmake.lua
@@ -20,12 +20,12 @@
-- define rule: c.openmp
rule("c.openmp")
- on_load(function (target)
+ on_config(function (target)
import("load")(target, "cc")
end)
-- define rule: c++.openmp
rule("c++.openmp")
- on_load(function (target)
+ on_config(function (target)
import("load")(target, "cxx")
end)
diff --git a/xmake/rules/c++/unity_build/unity_build.lua b/xmake/rules/c++/unity_build/unity_build.lua
new file mode 100644
index 000000000..608f79fed
--- /dev/null
+++ b/xmake/rules/c++/unity_build/unity_build.lua
@@ -0,0 +1,139 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file unity_build.lua
+--
+
+-- imports
+import("core.project.depend")
+
+function _merge_unityfile(target, sourcefile_unity, sourcefiles, opt)
+ local dependfile = target:dependfile(sourcefile_unity)
+ depend.on_changed(function ()
+
+ -- trace
+ vprint("generating.unityfile %s", sourcefile_unity)
+
+ -- do merge
+ local uniqueid = target:data("unity_build.uniqueid")
+ local unityfile = io.open(sourcefile_unity, "w")
+ for _, sourcefile in ipairs(sourcefiles) do
+ sourcefile = path.absolute(sourcefile)
+ sourcefile_unity = path.absolute(sourcefile_unity)
+ sourcefile = path.relative(sourcefile, path.directory(sourcefile_unity))
+ if uniqueid then
+ unityfile:print("#define %s %s", uniqueid, "unity_" .. hash.uuid():split("-", {plain = true})[1])
+ end
+ unityfile:print("#include \"%s\"", sourcefile)
+ if uniqueid then
+ unityfile:print("#undef %s", uniqueid)
+ end
+ end
+ unityfile:close()
+
+ end, {dependfile = dependfile, files = sourcefiles})
+end
+
+function generate_unityfiles(target, sourcebatch, opt)
+ local unity_batch = target:data("unity_build.unity_batch." .. sourcebatch.rulename)
+ if unity_batch then
+ for _, sourcefile_unity in ipairs(sourcebatch.sourcefiles) do
+ local sourceinfo = unity_batch[sourcefile_unity]
+ if sourceinfo then
+ local sourcefiles = sourceinfo.sourcefiles
+ if sourcefiles then
+ _merge_unityfile(target, sourcefile_unity, sourcefiles, opt)
+ end
+ end
+ end
+ end
+end
+
+-- use unity build
+--
+-- e.g.
+-- add_rules("c++.unity_build", {batchsize = 2})
+-- add_files("src/*.c", "src/*.cpp", {unity_ignored = true})
+-- add_files("src/foo/*.c", {unity_group = "foo"})
+-- add_files("src/bar/*.c", {unity_group = "bar"})
+--
+function main(target, sourcebatch)
+
+ -- get unit batch sources
+ local extraconf = target:extraconf("rules", sourcebatch.sourcekind == "cxx" and "c++.unity_build" or "c.unity_build")
+ local batchsize = extraconf and extraconf.batchsize
+ local uniqueid = extraconf and extraconf.uniqueid
+ local id = 1
+ local count = 0
+ local unity_batch = {}
+ local sourcefiles = {}
+ local objectfiles = {}
+ local dependfiles = {}
+ local sourcedir = path.join(target:autogendir({root = true}), "unity_build")
+ for idx, sourcefile in pairs(sourcebatch.sourcefiles) do
+ local sourcefile_unity
+ local objectfile = sourcebatch.objectfiles[idx]
+ local dependfile = sourcebatch.dependfiles[idx]
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig and fileconfig.unity_group then
+ sourcefile_unity = path.join(sourcedir, "unity_" .. fileconfig.unity_group .. path.extension(sourcefile))
+ elseif (fileconfig and fileconfig.unity_ignored) or (batchsize and batchsize <= 1) then
+ -- we do not add these files to unity file
+ table.insert(sourcefiles, sourcefile)
+ table.insert(objectfiles, objectfile)
+ table.insert(dependfiles, dependfile)
+ else
+ if batchsize and count > batchsize then
+ id = id + 1
+ end
+ sourcefile_unity = path.join(sourcedir, "unity_" .. hash.uuid(tostring(id)):split("-", {plain = true})[1] .. path.extension(sourcefile))
+ count = count + 1
+ end
+ if sourcefile_unity then
+ local sourceinfo = unity_batch[sourcefile_unity]
+ if not sourceinfo then
+ sourceinfo = {}
+ sourceinfo.objectfile = target:objectfile(sourcefile_unity)
+ sourceinfo.dependfile = target:dependfile(sourceinfo.objectfile)
+ unity_batch[sourcefile_unity] = sourceinfo
+ end
+ sourceinfo.sourcefiles = sourceinfo.sourcefiles or {}
+ table.insert(sourceinfo.sourcefiles, sourcefile)
+ end
+ end
+
+ -- use unit batch
+ for _, sourcefile_unity in ipairs(table.orderkeys(unity_batch)) do
+ local sourceinfo = unity_batch[sourcefile_unity]
+ if #sourceinfo.sourcefiles > 1 then
+ table.insert(sourcefiles, sourcefile_unity)
+ table.insert(objectfiles, sourceinfo.objectfile)
+ table.insert(dependfiles, sourceinfo.dependfile)
+ else
+ table.insert(sourcefiles, sourceinfo.sourcefiles[1])
+ table.insert(objectfiles, sourceinfo.objectfile)
+ table.insert(dependfiles, sourceinfo.dependfile)
+ end
+ end
+ sourcebatch.sourcefiles = sourcefiles
+ sourcebatch.objectfiles = objectfiles
+ sourcebatch.dependfiles = dependfiles
+
+ -- save unit batch
+ target:data_set("unity_build.uniqueid", uniqueid)
+ target:data_set("unity_build.unity_batch." .. sourcebatch.rulename, unity_batch)
+end
diff --git a/xmake/rules/c++/unity_build/xmake.lua b/xmake/rules/c++/unity_build/xmake.lua
new file mode 100644
index 000000000..e0dfa9660
--- /dev/null
+++ b/xmake/rules/c++/unity_build/xmake.lua
@@ -0,0 +1,63 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+rule("c.unity_build")
+ after_load(function (target)
+ import("unity_build")
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches then
+ local sourcebatch = sourcebatches["c.build"]
+ if sourcebatch then
+ unity_build(target, sourcebatch)
+ end
+ end
+ end)
+ before_build(function (target, opt)
+ import("unity_build")
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches then
+ local sourcebatch = sourcebatches["c.build"]
+ if sourcebatch then
+ unity_build.generate_unityfiles(target, sourcebatch, opt)
+ end
+ end
+ end)
+
+rule("c++.unity_build")
+ after_load(function (target)
+ import("unity_build")
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches then
+ local sourcebatch = sourcebatches["c++.build"]
+ if sourcebatch then
+ unity_build(target, sourcebatch)
+ end
+ end
+ end)
+ before_build(function (target, opt)
+ import("unity_build")
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches then
+ local sourcebatch = sourcebatches["c++.build"]
+ if sourcebatch then
+ unity_build.generate_unityfiles(target, sourcebatch, opt)
+ end
+ end
+ end)
diff --git a/xmake/rules/cuda/devlink/xmake.lua b/xmake/rules/cuda/devlink/xmake.lua
index e92a0b779..fb1f603b0 100644
--- a/xmake/rules/cuda/devlink/xmake.lua
+++ b/xmake/rules/cuda/devlink/xmake.lua
@@ -34,7 +34,7 @@ rule("cuda.build.devlink")
import("core.project.depend")
import("core.tool.linker")
import("core.platform.platform")
- import("private.utils.progress")
+ import("utils.progress")
-- disable devlink?
if target:values("cuda.build.devlink") == false then
diff --git a/xmake/rules/cuda/env/xmake.lua b/xmake/rules/cuda/env/xmake.lua
index e6e802d71..96d587e41 100644
--- a/xmake/rules/cuda/env/xmake.lua
+++ b/xmake/rules/cuda/env/xmake.lua
@@ -21,7 +21,7 @@
-- define rule: environment
rule("cuda.env")
- before_load(function (target)
+ on_load(function (target)
-- imports
import("detect.sdks.find_cuda")
diff --git a/xmake/rules/cuda/gencodes/xmake.lua b/xmake/rules/cuda/gencodes/xmake.lua
index 0845178fe..c7ee45050 100644
--- a/xmake/rules/cuda/gencodes/xmake.lua
+++ b/xmake/rules/cuda/gencodes/xmake.lua
@@ -34,7 +34,7 @@ rule("cuda.gencodes")
-- if no available device is found, no `-gencode` flags will be added
-- @seealso xmake/modules/lib/detect/find_cudadevices
--
- before_load(function (target)
+ on_config(function (target)
-- imports
import("core.platform.platform")
@@ -47,14 +47,14 @@ rule("cuda.gencodes")
local known_r_archs = hashset.of(20, 30, 32, 35, 37, 50, 52, 53, 60, 61, 62, 70, 72, 75, 80)
local function nf_cugencode(archs)
- if type(archs) ~= 'string' then
+ if type(archs) ~= "string" then
return nil
end
archs = archs:trim():lower()
- if archs == 'native' then
+ if archs == "native" then
local device = find_cudadevices({ skip_compute_mode_prohibited = true, order_by_flops = true })[1]
if device then
- return nf_cugencode('sm_' .. device.major .. device.minor)
+ return nf_cugencode("sm_" .. device.major .. device.minor)
end
return nil
end
@@ -68,13 +68,13 @@ rule("cuda.gencodes")
end
local arch = tonumber(value:sub(#prefix + 1)) or tonumber(value:sub(#prefix + 2))
if arch == nil then
- raise("Unknown architecture: " .. value)
+ raise("unknown architecture: " .. value)
end
if not know_list:has(arch) then
if arch <= table.maxn(know_list:data()) then
- raise("Unknown architecture: " .. prefix .. "_" .. arch)
+ raise("unknown architecture: " .. prefix .. "_" .. arch)
else
- utils.warning("Unknown architecture: " .. prefix .. "_" .. arch)
+ utils.warning("unknown architecture: " .. prefix .. "_" .. arch)
end
end
return arch
@@ -82,20 +82,20 @@ rule("cuda.gencodes")
for _, v in ipairs(archs:split(',')) do
local arch = v:trim()
- local temp_r_arch = parse_arch(arch, 'sm', known_r_archs)
+ local temp_r_arch = parse_arch(arch, "sm", known_r_archs)
if temp_r_arch then
table.insert(r_archs, temp_r_arch)
end
- local temp_v_arch = parse_arch(arch, 'compute', known_v_archs)
+ local temp_v_arch = parse_arch(arch, "compute", known_v_archs)
if temp_v_arch then
if v_arch ~= nil then
- raise("More than one virtual architecture is defined in one gpu gencode option: compute_" .. v_arch .. " and compute_" .. temp_v_arch)
+ raise("more than one virtual architecture is defined in one gpu gencode option: compute_" .. v_arch .. " and compute_" .. temp_v_arch)
end
v_arch = temp_v_arch
end
if not (temp_r_arch or temp_v_arch) then
- raise("Unknown architecture: " .. arch)
+ raise("unknown architecture: " .. arch)
end
end
@@ -105,27 +105,28 @@ rule("cuda.gencodes")
if #r_archs == 0 then
return {
- clang = '--cuda-gpu-arch=sm_' .. v_arch
- , nvcc = '-gencode arch=compute_' .. v_arch .. ',code=compute_' .. v_arch }
+ clang = "--cuda-gpu-arch=sm_" .. v_arch,
+ nvcc = "-gencode arch=compute_" .. v_arch .. ",code=compute_" .. v_arch
+ }
end
if v_arch then
table.insert(r_archs, v_arch)
else
- v_arch = math.min(unpack(r_archs))
+ v_arch = math.min(table.unpack(r_archs))
end
r_archs = table.unique(r_archs)
local clang_flags = {}
for _, r_arch in ipairs(r_archs) do
- table.insert(clang_flags, '--cuda-gpu-arch=sm_' .. r_arch)
+ table.insert(clang_flags, "--cuda-gpu-arch=sm_" .. r_arch)
end
local nvcc_flags = nil
if #r_archs == 1 then
- nvcc_flags = '-gencode arch=compute_' .. v_arch .. ',code=sm_' .. r_archs[1]
+ nvcc_flags = "-gencode arch=compute_" .. v_arch .. ",code=sm_" .. r_archs[1]
else
- nvcc_flags = '-gencode arch=compute_' .. v_arch .. ',code=[sm_' .. table.concat(r_archs, ',sm_') .. ']'
+ nvcc_flags = "-gencode arch=compute_" .. v_arch .. ",code=[sm_" .. table.concat(r_archs, ",sm_") .. "]"
end
return { clang = clang_flags, nvcc = nvcc_flags }
@@ -138,13 +139,12 @@ rule("cuda.gencodes")
for _, v in ipairs(cugencodes) do
local flag = nf_cugencode(v)
if flag then
- local tool, toolname = platform.tool("cu")
- if (toolname or path.basename(tool)) == "nvcc" then
- target:add('cuflags', flag.nvcc)
+ if target:has_tool("cu", "nvcc") then
+ target:add("cuflags", flag.nvcc)
else
- target:add('cuflags', flag.clang)
+ target:add("cuflags", flag.clang)
end
- target:add('culdflags', flag.nvcc)
+ target:add("culdflags", flag.nvcc)
end
end
end)
diff --git a/xmake/rules/go/build/object.lua b/xmake/rules/go/build/object.lua
index cf6a1c9ff..21436be47 100644
--- a/xmake/rules/go/build/object.lua
+++ b/xmake/rules/go/build/object.lua
@@ -21,19 +21,13 @@
-- imports
import("core.base.option")
import("core.base.hashset")
-import("core.theme.theme")
import("core.tool.compiler")
import("core.project.depend")
+import("utils.progress")
-- build the source files
function main(target, sourcebatch, opt)
-
- -- is verbose?
- local verbose = option.get("verbose")
-
- -- get progress range
- local progress = assert(opt.progress, "no progress!")
-
+
-- get source files and kind
local sourcefiles = sourcebatch.sourcefiles
local sourcekind = sourcebatch.sourcekind
@@ -72,18 +66,11 @@ function main(target, sourcebatch, opt)
-- trace progress info
for index, sourcefile in ipairs(sourcefiles) do
- local progress_prefix = "${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} "
- if verbose then
- cprint(progress_prefix .. "${dim color.build.object}compiling.$(mode) %s", progress, sourcefile)
- else
- cprint(progress_prefix .. "${color.build.object}compiling.$(mode) %s", progress, sourcefile)
- end
+ progress.show(opt.progress, "${color.build.object}compiling.$(mode) %s", sourcefile)
end
-- trace verbose info
- if verbose then
- print(compinst:compcmd(sourcefiles, objectfile, {compflags = compflags}))
- end
+ vprint(compinst:compcmd(sourcefiles, objectfile, {compflags = compflags}))
-- compile it
dependinfo.files = {}
diff --git a/xmake/rules/go/xmake.lua b/xmake/rules/go/xmake.lua
index ef6f04321..58890e260 100644
--- a/xmake/rules/go/xmake.lua
+++ b/xmake/rules/go/xmake.lua
@@ -24,6 +24,10 @@ rule("go.build")
on_load(function (target)
-- we disable to build across targets in parallel, because the source files may depend on other target modules
target:set("policy", "build.across_targets_in_parallel", false)
+ -- xxx.a
+ if target:is_static() then
+ target:set("prefixname", "")
+ end
end)
on_build_files("build.object")
diff --git a/xmake/rules/luarocks/module/xmake.lua b/xmake/rules/luarocks/module/xmake.lua
index e74080912..530e35070 100644
--- a/xmake/rules/luarocks/module/xmake.lua
+++ b/xmake/rules/luarocks/module/xmake.lua
@@ -19,7 +19,7 @@
--
rule("luarocks.module")
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.cache.detectcache")
diff --git a/xmake/rules/mdk/xmake.lua b/xmake/rules/mdk/xmake.lua
new file mode 100644
index 000000000..0c491b528
--- /dev/null
+++ b/xmake/rules/mdk/xmake.lua
@@ -0,0 +1,43 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+rule("mdk.console")
+ on_load(function (target)
+ -- we disable checking flags for cross toolchain automatically
+ target:set("policy", "check.auto_ignore_flags", false)
+ target:set("policy", "check.auto_map_flags", false)
+
+ -- set default output binary
+ target:set("kind", "binary")
+ if not target:get("extension") then
+ target:set("extension", ".axf")
+ end
+ end)
+
+rule("mdk.static")
+ on_load(function (target)
+ -- we disable checking flags for cross toolchain automatically
+ target:set("policy", "check.auto_ignore_flags", false)
+ target:set("policy", "check.auto_map_flags", false)
+
+ -- set default output binary
+ target:set("kind", "static")
+ end)
+
diff --git a/xmake/rules/nim/build/target.lua b/xmake/rules/nim/build/target.lua
new file mode 100644
index 000000000..79e271063
--- /dev/null
+++ b/xmake/rules/nim/build/target.lua
@@ -0,0 +1,86 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file target.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.hashset")
+import("core.tool.compiler")
+import("core.project.depend")
+import("utils.progress")
+
+-- build the source files
+function build_sourcefiles(target, sourcebatch, opt)
+
+ -- get the target file
+ local targetfile = target:targetfile()
+
+ -- get source files and kind
+ local sourcefiles = sourcebatch.sourcefiles
+ local sourcekind = sourcebatch.sourcekind
+
+ -- get depend file
+ local dependfile = target:dependfile(targetfile)
+
+ -- load compiler
+ local compinst = compiler.load(sourcekind, {target = target})
+
+ -- get compile flags
+ local compflags = compinst:compflags({target = target})
+
+ -- load dependent info
+ local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
+
+ -- need build this object?
+ local depvalues = {compinst:program(), compflags}
+ if not depend.is_changed(dependinfo, {lastmtime = os.mtime(targetfile), values = depvalues}) then
+ return
+ end
+
+ -- trace progress into
+ progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", path.filename(targetfile))
+
+ -- trace verbose info
+ vprint(compinst:buildcmd(sourcefiles, targetfile, {target = target, compflags = compflags}))
+
+ -- flush io buffer to update progress info
+ io.flush()
+
+ -- compile it
+ dependinfo.files = {}
+ assert(compinst:build(sourcefiles, targetfile, {target = target, dependinfo = dependinfo, compflags = compflags}))
+
+ -- update files and values to the dependent file
+ dependinfo.values = depvalues
+ table.join2(dependinfo.files, sourcefiles)
+ depend.save(dependinfo, dependfile)
+end
+
+-- build target
+function main(target, opt)
+
+ -- @note only support one source kind!
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches then
+ local sourcebatch = sourcebatches["nim.build"]
+ if sourcebatch then
+ build_sourcefiles(target, sourcebatch, opt)
+ end
+ end
+end
diff --git a/xmake/rules/nim/xmake.lua b/xmake/rules/nim/xmake.lua
new file mode 100644
index 000000000..7d65c9c12
--- /dev/null
+++ b/xmake/rules/nim/xmake.lua
@@ -0,0 +1,37 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- define rule: nim.build
+rule("nim.build")
+ set_sourcekinds("nc")
+ on_load(function (target)
+ local cachedir = path.join(target:autogendir(), "nimcache")
+ target:add("ncflags", "--nimcache:" .. cachedir, {force = true})
+ end)
+ on_build("build.target")
+
+-- define rule: nim
+rule("nim")
+
+ -- add build rules
+ add_deps("nim.build")
+
+ -- inherit links and linkdirs of all dependent targets by default
+ add_deps("utils.inherit.links")
diff --git a/xmake/rules/pascal/build/target.lua b/xmake/rules/pascal/build/target.lua
new file mode 100644
index 000000000..646474606
--- /dev/null
+++ b/xmake/rules/pascal/build/target.lua
@@ -0,0 +1,88 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file target.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.hashset")
+import("core.theme.theme")
+import("core.tool.compiler")
+import("core.project.depend")
+import("utils.progress")
+
+-- build the source files
+function build_sourcefiles(target, sourcebatch, opt)
+
+ -- is verbose?
+ local verbose = option.get("verbose")
+
+ -- get the target file
+ local targetfile = target:targetfile()
+
+ -- get source files and kind
+ local sourcefiles = sourcebatch.sourcefiles
+ local sourcekind = sourcebatch.sourcekind
+
+ -- get depend file
+ local dependfile = target:dependfile(targetfile)
+
+ -- load compiler
+ local compinst = compiler.load(sourcekind, {target = target})
+
+ -- get compile flags
+ local compflags = compinst:compflags({target = target})
+
+ -- load dependent info
+ local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
+
+ -- need build this object?
+ local depvalues = {compinst:program(), compflags}
+ if not depend.is_changed(dependinfo, {lastmtime = os.mtime(targetfile), values = depvalues}) then
+ return
+ end
+
+ -- trace progress into
+ progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", path.filename(targetfile))
+
+ -- trace verbose info
+ if verbose then
+ print(compinst:buildcmd(sourcefiles, targetfile, {target = target, compflags = compflags}))
+ end
+
+ -- compile it
+ dependinfo.files = {}
+ assert(compinst:build(sourcefiles, targetfile, {target = target, dependinfo = dependinfo, compflags = compflags}))
+
+ -- update files and values to the dependent file
+ dependinfo.values = depvalues
+ table.join2(dependinfo.files, sourcefiles)
+ depend.save(dependinfo, dependfile)
+end
+
+-- build target
+function main(target, opt)
+
+ -- @note only support one source kind!
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ if sourcebatch.sourcekind == "pc" then
+ build_sourcefiles(target, sourcebatch, opt)
+ break
+ end
+ end
+end
diff --git a/xmake/rules/pascal/xmake.lua b/xmake/rules/pascal/xmake.lua
new file mode 100644
index 000000000..5961c08d3
--- /dev/null
+++ b/xmake/rules/pascal/xmake.lua
@@ -0,0 +1,33 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- define rule: pascal.build
+rule("pascal.build")
+ set_sourcekinds("pc")
+ on_build("build.target")
+
+-- define rule: pascal
+rule("pascal")
+
+ -- add build rules
+ add_deps("pascal.build")
+
+ -- inherit links and linkdirs of all dependent targets by default
+ add_deps("utils.inherit.links")
diff --git a/xmake/rules/platform/linux/driver/driver_modules.lua b/xmake/rules/platform/linux/driver/driver_modules.lua
new file mode 100644
index 000000000..4f2640c83
--- /dev/null
+++ b/xmake/rules/platform/linux/driver/driver_modules.lua
@@ -0,0 +1,299 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file driver_modules.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.depend")
+import("core.cache.memcache")
+import("lib.detect.find_tool")
+import("utils.progress")
+import("private.tools.ccache")
+
+-- get linux-headers sdk
+function _get_linux_headers_sdk(target)
+ local linux_headersdir = target:values("linux.driver.linux-headers")
+ if linux_headersdir then
+ return {sdkdir = linux_headersdir, includedir = path.join(linux_headersdir, "include")}
+ end
+ local linux_headers = assert(target:pkg("linux-headers"), "please add `add_requires(\"linux-headers\", {configs = {driver_modules = true}})` and `add_packages(\"linux-headers\")` to the given target!")
+ local includedirs = linux_headers:get("includedirs") or linux_headers:get("sysincludedirs")
+ local version = linux_headers:version()
+ local includedir
+ for _, dir in ipairs(includedirs) do
+ if dir:find("linux-headers", 1, true) then
+ includedir = dir
+ linux_headersdir = path.directory(dir)
+ break
+ end
+ end
+ assert(linux_headersdir, "linux-headers not found!")
+ if not os.isfile(path.join(includedir, "generated/autoconf.h")) and
+ not os.isfile(path.join(includedir, "config/auto.conf")) then
+ raise("kernel configuration is invalid. include/generated/autoconf.h or include/config/auto.conf are missing.")
+ end
+ return {version = version, sdkdir = linux_headersdir, includedir = includedir}
+end
+
+-- get cflags from make
+function _get_cflags_from_make(target, sdkdir)
+ local key = target:plat() .. target:arch()
+ local cflags = memcache.get2("linux.driver", key, "cflags")
+ local ldflags_o = memcache.get2("linux.driver", key, "ldflags_o")
+ local ldflags_ko = memcache.get2("linux.driver", key, "ldflags_ko")
+ if cflags == nil then
+ local make = assert(find_tool("make"), "make not found!")
+ local tmpdir = os.tmpfile() .. ".dir"
+ local makefile = path.join(tmpdir, "Makefile")
+ local stubfile = path.join(tmpdir, "src/stub.c")
+ local foofile = path.join(tmpdir, "src/foo.c")
+ io.writefile(makefile, [[obj-m := stub.o
+stub-objs := src/stub.o src/foo.o]])
+ io.writefile(foofile, "")
+ io.writefile(stubfile, [[
+#include <linux/init.h>
+#include <linux/module.h>
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Ruki");
+MODULE_DESCRIPTION("A simple Hello World Module");
+MODULE_ALIAS("a simplest module");
+
+int hello_init(void) {
+ printk(KERN_INFO "Hello World\n");
+ return 0;
+}
+
+void hello_exit(void) {
+ printk(KERN_INFO "Goodbye World\n");
+}
+
+module_init(hello_init);
+module_exit(hello_exit);
+ ]])
+ local argv = {"-C", sdkdir, "V=1", "M=" .. tmpdir, "modules"}
+ if not target:is_plat(os.subhost()) then
+ -- e.g. $(MAKE) -C $(KERN_DIR) V=1 ARCH=arm64 CROSS_COMPILE=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- M=$(PWD) modules
+ local arch
+ if target:is_arch("arm", "armv7") then
+ arch = "arm"
+ elseif target:is_arch("arm64", "arm64-v8a") then
+ arch = "arm64"
+ elseif target:is_arch("mips") then
+ arch = "mips"
+ elseif target:is_arch("ppc", "ppc64", "powerpc", "powerpc64") then
+ arch = "powerpc"
+ end
+ assert(arch, "unknown arch(%s)!", target:arch())
+ local cc = target:tool("cc")
+ local cross = cc:gsub("%-gcc$", "-")
+ table.insert(argv, "ARCH=" .. arch)
+ table.insert(argv, "CROSS_COMPILE=" .. cross)
+ end
+ local result, errors = try {function () return os.iorunv(make.program, argv, {curdir = tmpdir}) end}
+ if result then
+ for _, line in ipairs(result:split("\n", {plain = true})) do
+ if line:endswith("stub.c") then
+ local include_cflag = false
+ for _, cflag in ipairs(line:split("%s+")) do
+ local has_cflag = false
+ if cflag:startswith("-f") or cflag:startswith("-m")
+ or (cflag:startswith("-W") and not cflag:startswith("-Wp,-MMD,") and not cflag:startswith("-Wp,-MD,"))
+ or (cflag:startswith("-D") and not cflag:find("KBUILD_MODNAME=") and not cflag:find("KBUILD_BASENAME=")) then
+ has_cflag = true
+ local macro = cflag:match("%-D\"(.+)\"") -- -D"KBUILD_XXX=xxx"
+ if macro then
+ cflag = "-D" .. macro
+ end
+ elseif cflag == "-I" or cflag == "-isystem" or cflag == "-include" then
+ include_cflag = cflag
+ elseif cflag:startswith("-I") or include_cflag then
+ local includedir = cflag
+ if cflag:startswith("-I") then
+ includedir = cflag:sub(3)
+ end
+ if not path.is_absolute(includedir) then
+ includedir = path.absolute(includedir, sdkdir)
+ end
+ if cflag:startswith("-I") then
+ cflag = "-I" .. includedir
+ else
+ cflag = include_cflag .. " " .. includedir
+ end
+ has_cflag = true
+ include_cflag = nil
+ end
+ if has_cflag then
+ cflags = cflags or {}
+ table.insert(cflags, cflag)
+ end
+ end
+ end
+ local ldflags = line:match("%-ld (.+) %-o ") or line:match("ld (.+) %-o ")
+ if ldflags then
+ local ko = ldflags:find("-T ", 1, true)
+ for _, ldflag in ipairs(os.argv(ldflags)) do
+ if ldflag:endswith(".lds") then
+ if not path.is_absolute(ldflag) then
+ ldflag = path.absolute(ldflag, sdkdir)
+ end
+ end
+ if ko then
+ -- e.g. aarch64-linux-gnu-ld -r -EL -maarch64elf --build-id=sha1 -T scripts/module.lds -o hello.ko hello.o hello.mod.o
+ ldflags_ko = ldflags_ko or {}
+ table.insert(ldflags_ko, ldflag)
+ else
+ -- e.g. aarch64-linux-gnu-ld -EL -maarch64elf -r -o hello.o xxx.o
+ ldflags_o = ldflags_o or {}
+ table.insert(ldflags_o, ldflag)
+ end
+ end
+ end
+ if cflags and ldflags_o and ldflags_ko then
+ break
+ end
+ end
+ else
+ if option.get("diagnosis") then
+ print("rule(platform.linux.driver): cannot get cflags from make!")
+ print(errors)
+ end
+ end
+ os.tryrm(tmpdir)
+ memcache.set2("linux.driver", key, "cflags", cflags or false)
+ end
+ return cflags or nil, ldflags_o or nil, ldflags_ko or nil
+end
+
+function load(target)
+ -- we need only need binary kind, because we will rewrite on_link
+ target:set("kind", "binary")
+ target:set("extension", ".ko")
+end
+
+function config(target)
+
+ -- get and save linux-headers sdk
+ local linux_headers = _get_linux_headers_sdk(target)
+ target:data_set("linux.driver.linux_headers", linux_headers)
+
+ -- check compiler, we must use gcc
+ assert(target:has_tool("cc", "gcc"), "we must use gcc compiler!")
+
+ -- check rules
+ for _, rulename in ipairs({"mode.release", "mode.debug", "mode.releasedbg", "mode.minsizerel", "mode.asan", "mode.tsan"}) do
+ assert(not target:rule(rulename), "target(%s) is linux driver module, it need not rule(%s)!", target:name(), rulename)
+ end
+
+ -- we need disable includedirs from add_packages("linux-headers")
+ if target:pkg("linux-headers") then
+ target:pkg("linux-headers"):set("includedirs", nil)
+ target:pkg("linux-headers"):set("sysincludedirs", nil)
+ end
+
+ -- add compilation flags
+ target:add("defines", "KBUILD_MODNAME=\"" .. target:name() .. "\"")
+ for _, sourcefile in ipairs(target:sourcefiles()) do
+ target:fileconfig_set(sourcefile, {defines = "KBUILD_BASENAME=\"" .. path.basename(sourcefile) .. "\""})
+ end
+ local cflags, ldflags_o, ldflags_ko = _get_cflags_from_make(target, linux_headers.sdkdir)
+ if cflags then
+ target:add("cflags", cflags, {force = true})
+ target:data_set("linux.driver.ldflags_o", ldflags_o)
+ target:data_set("linux.driver.ldflags_ko", ldflags_ko)
+ end
+end
+
+function link(target, opt)
+ local targetfile = target:targetfile()
+ local dependfile = target:dependfile(targetfile)
+ local objectfiles = target:objectfiles()
+ depend.on_changed(function ()
+
+ -- trace
+ progress.show(opt.progress, "${color.build.object}linking.$(mode) %s", targetfile)
+
+ -- get module scripts
+ local modpost
+ local linux_headers = target:data("linux.driver.linux_headers")
+ if linux_headers then
+ modpost = path.join(linux_headers.sdkdir, "scripts", "mod", "modpost")
+ end
+ assert(modpost and os.isfile(modpost), "scripts/mod/modpost not found!")
+
+ -- get ld
+ local ld = target:tool("ld")
+ assert(ld, "ld not found!")
+ ld = ld:gsub("gcc$", "ld")
+ ld = ld:gsub("g%+%+$", "ld")
+
+ -- link target.o
+ local argv = {}
+ local ldflags_o = target:data("linux.driver.ldflags_o")
+ if ldflags_o then
+ table.join2(argv, ldflags_o)
+ end
+ local targetfile_o = target:objectfile(targetfile)
+ table.join2(argv, "-o", targetfile_o)
+ table.join2(argv, objectfiles)
+ os.mkdir(path.directory(targetfile_o))
+ os.vrunv(ld, argv)
+
+ -- generate target.mod
+ local targetfile_mod = targetfile_o:gsub("%.o$", ".mod")
+ io.writefile(targetfile_mod, table.concat(objectfiles, " ") .. "\n\n")
+
+ -- generate .sourcename.o.cmd
+ -- we need only touch an empty file, otherwise modpost command will raise error.
+ for _, objectfile in ipairs(objectfiles) do
+ local objectdir = path.directory(objectfile)
+ local objectname = path.filename(objectfile)
+ local cmdfile = path.join(objectdir, "." .. objectname .. ".cmd")
+ io.writefile(cmdfile, "")
+ end
+
+ -- generate target.mod.c
+ local orderfile = path.join(path.directory(targetfile_o), "modules.order")
+ local symversfile = path.join(path.directory(targetfile_o), "Module.symvers")
+ argv = {"-m", "-a", "-o", symversfile, "-e", "-N", "-T", "-"}
+ io.writefile(orderfile, targetfile_o .. "\n")
+ os.vrunv(modpost, argv, {stdin = orderfile})
+
+ -- compile target.mod.c
+ local targetfile_mod_c = targetfile_o:gsub("%.o$", ".mod.c")
+ local targetfile_mod_o = targetfile_o:gsub("%.o$", ".mod.o")
+ local compinst = target:compiler("cc")
+ if option.get("verbose") then
+ print(compinst:compcmd(targetfile_mod_c, targetfile_mod_o, {target = target, rawargs = true}))
+ end
+ assert(compinst:compile(targetfile_mod_c, targetfile_mod_o, {target = target}))
+
+ -- link target.ko
+ argv = {}
+ local ldflags_ko = target:data("linux.driver.ldflags_ko")
+ if ldflags_ko then
+ table.join2(argv, ldflags_ko)
+ end
+ local targetfile_o = target:objectfile(targetfile)
+ table.join2(argv, "-o", targetfile, targetfile_o, targetfile_mod_o)
+ os.mkdir(path.directory(targetfile))
+ os.vrunv(ld, argv)
+
+ end, {dependfile = dependfile, lastmtime = os.mtime(target:targetfile()), files = objectfiles})
+end
diff --git a/xmake/rules/platform/linux/driver/xmake.lua b/xmake/rules/platform/linux/driver/xmake.lua
new file mode 100644
index 000000000..8192b9a7f
--- /dev/null
+++ b/xmake/rules/platform/linux/driver/xmake.lua
@@ -0,0 +1,33 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- build linux driver module
+rule("platform.linux.driver")
+ set_sourcekinds("cc")
+ on_load(function (target)
+ import("driver_modules").load(target)
+ end)
+ on_config(function (target)
+ import("driver_modules").config(target)
+ end)
+ on_link(function (target, opt)
+ import("driver_modules").link(target, opt)
+ end)
+
diff --git a/xmake/rules/platform/windows/def/xmake.lua b/xmake/rules/platform/windows/def/xmake.lua
index 06e960380..7919553de 100644
--- a/xmake/rules/platform/windows/def/xmake.lua
+++ b/xmake/rules/platform/windows/def/xmake.lua
@@ -22,8 +22,7 @@
rule("platform.windows.def")
set_extensions(".def")
on_config("windows", function (target)
- local _, toolname = target:tool("ld")
- if toolname == "link" then
+ if target:has_tool("ld", "link") then
for _, sourcebatch in pairs(target:sourcebatches()) do
if sourcebatch.rulename == "platform.windows.def" then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
diff --git a/xmake/rules/platform/windows/manifest/xmake.lua b/xmake/rules/platform/windows/manifest/xmake.lua
index efb750edd..b476faeed 100644
--- a/xmake/rules/platform/windows/manifest/xmake.lua
+++ b/xmake/rules/platform/windows/manifest/xmake.lua
@@ -23,8 +23,7 @@
rule("platform.windows.manifest")
set_extensions(".manifest")
on_config("windows", function (target)
- local _, toolname = target:tool("ld")
- if toolname == "link" then
+ if target:has_tool("ld", "link") then
local manifest = false
for _, sourcebatch in pairs(target:sourcebatches()) do
if sourcebatch.rulename == "platform.windows.manifest" then
diff --git a/xmake/rules/plugin/vsxmake/xmake.lua b/xmake/rules/plugin/vsxmake/xmake.lua
index 88693599f..bb0f231e4 100644
--- a/xmake/rules/plugin/vsxmake/xmake.lua
+++ b/xmake/rules/plugin/vsxmake/xmake.lua
@@ -35,12 +35,17 @@ rule("plugin.vsxmake.autoupdate")
import("core.project.config")
import("core.project.depend")
import("core.project.project")
+ import("core.cache.localcache")
import("core.base.task")
-- run only once for all xmake process in vs
local tmpfile = path.join(config.buildir(), ".gens", "rules", "plugin.vsxmake.autoupdate")
local dependfile = tmpfile .. ".d"
local lockfile = io.openlock(tmpfile .. ".lock")
+ local kind = localcache.get("vsxmake", "kind")
+ local modes = localcache.get("vsxmake", "modes")
+ local archs = localcache.get("vsxmake", "archs")
+ local outputdir = localcache.get("vsxmake", "outputdir")
if lockfile:trylock() then
if os.getenv("XMAKE_IN_VSTUDIO") then
local sourcefiles = {}
@@ -50,8 +55,8 @@ rule("plugin.vsxmake.autoupdate")
table.sort(sourcefiles)
depend.on_changed(function ()
-- we use task instead of os.exec("xmake") to avoid the project lock
- print("update vsxmake project ..")
- task.run("project", {kind = "vsxmake"})
+ print("update vsxmake project -k %s %s ..", kind or "vsxmake", outputdir or "")
+ task.run("project", {kind = kind or "vsxmake", modes = modes, archs = archs, outputdir = outputdir})
print("update vsxmake project ok")
end, {dependfile = dependfile,
files = project.allfiles(),
diff --git a/xmake/rules/python/xmake.lua b/xmake/rules/python/xmake.lua
new file mode 100644
index 000000000..823495485
--- /dev/null
+++ b/xmake/rules/python/xmake.lua
@@ -0,0 +1,43 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- @see https://github.com/xmake-io/xmake/issues/1896
+rule("python.library")
+ on_load(function (target)
+ target:set("kind", "shared")
+ target:set("prefixname", "_")
+ local soabi = target:extraconf("rules", "python.library", "soabi")
+ if soabi then
+ import("lib.detect.find_tool")
+ local python = assert(find_tool("python3"), "python not found!")
+ local result = try { function() return os.iorunv(python.program, {"-c", "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"}) end}
+ if result then
+ result = result:trim()
+ if result ~= "None" then
+ target:set("extension", result)
+ end
+ end
+ else
+ if target:is_plat("windows") then
+ target:set("extension", ".pyd")
+ end
+ end
+ end)
+
diff --git a/xmake/rules/qt/deploy/android.lua b/xmake/rules/qt/deploy/android.lua
index 97f97ea7a..326addbc1 100644
--- a/xmake/rules/qt/deploy/android.lua
+++ b/xmake/rules/qt/deploy/android.lua
@@ -25,7 +25,7 @@ import("core.base.semver")
import("core.project.config")
import("core.project.depend")
import("core.tool.toolchain")
-import("private.utils.progress")
+import("utils.progress")
-- escape path
function _escape_path(p)
@@ -71,6 +71,9 @@ function main(target, opt)
-- get androiddeployqt
local androiddeployqt = path.join(qt.bindir, "androiddeployqt" .. (is_host("windows") and ".exe" or ""))
+ if not os.isexec(androiddeployqt) and qt.bindir_host then
+ androiddeployqt = path.join(qt.bindir_host, "androiddeployqt" .. (is_host("windows") and ".exe" or ""))
+ end
assert(os.isexec(androiddeployqt), "androiddeployqt not found!")
-- get working directory
@@ -120,18 +123,6 @@ function main(target, opt)
os.cp(target:targetfile(), path.join(android_buildir, "libs", target_arch, path.filename(target:targetfile())))
end
- -- get the android srcs directory, e.g. android-build/java/res/values
- local android_srcs
- if qt_sdkver and qt_sdkver:ge("5.14") then
- -- @note we need patch values/res/strings.xml for Qt 5.14.0
- local valuesdir = path.join(android_buildir, "java", "res", "values")
- if not os.isdir(valuesdir) then
- os.mkdir(valuesdir)
- end
- os.cp(path.join(qt.sdkdir, "src", "android", "java", "res", "values", "*"), valuesdir)
- android_srcs = path.join(android_buildir, "java")
- end
-
-- get stdcpp path
local stdcpp_path = path.join(ndk, "sources/cxx-stl/llvm-libc++/libs", target_arch, "libc++_shared.so")
if qt_sdkver and qt_sdkver:ge("5.14") then
@@ -159,9 +150,21 @@ function main(target, opt)
settings_file:print(' "ndk-host": "%s",', ndk_host)
settings_file:print(' "target-architecture": "%s",', target_arch)
settings_file:print(' "qml-root-path": "%s",', _escape_path(os.projectdir()))
- if android_srcs then
- settings_file:print(' "android-package-source-directory": "%s",', _escape_path(android_srcs))
- --settings_file:print(' "android-extra-libs":"c:/libs",')
+ -- for 6.2.x
+ local qmlimportscanner = path.join(qt.libexecdir, "qmlimportscanner" .. (is_host("windows") and ".exe" or ""))
+ if not os.isexec(qmlimportscanner) and qt.libexecdir_host then
+ qmlimportscanner = path.join(qt.libexecdir_host, "qmlimportscanner" .. (is_host("windows") and ".exe" or ""))
+ end
+ if os.isexec(qmlimportscanner) then
+ settings_file:print(' "qml-importscanner-binary": "%s",', qmlimportscanner)
+ end
+ local minsdkversion = target:values("qt.android.minsdkversion")
+ if minsdkversion then
+ settings_file:print(' "android-min-sdk-version": "%s",', tostring(minsdkversion))
+ end
+ local targetsdkversion = target:values("qt.android.targetsdkversion")
+ if targetsdkversion then
+ settings_file:print(' "android-target-sdk-version": "%s",', tostring(targetsdkversion))
end
settings_file:print(' "useLLVM": true,')
if qt_sdkver and qt_sdkver:ge("5.14") then
@@ -194,7 +197,6 @@ function main(target, opt)
-- do deploy
local argv = {"--input", android_deployment_settings,
"--output", android_buildir,
- "--android-platform", android_platform,
"--jdk", java_home,
"--gradle", "--no-gdbserver"}
if option.get("verbose") and option.get("diagnosis") then
diff --git a/xmake/rules/qt/deploy/macosx.lua b/xmake/rules/qt/deploy/macosx.lua
index 5f7b8390d..26df10b14 100644
--- a/xmake/rules/qt/deploy/macosx.lua
+++ b/xmake/rules/qt/deploy/macosx.lua
@@ -25,7 +25,7 @@ import("core.project.config")
import("core.project.depend")
import("core.tool.toolchain")
import("lib.detect.find_path")
-import("private.utils.progress")
+import("utils.progress")
-- save Info.plist
function _save_info_plist(target, info_plist_file)
diff --git a/xmake/rules/qt/load.lua b/xmake/rules/qt/load.lua
index 03599f7e2..c5bec10af 100644
--- a/xmake/rules/qt/load.lua
+++ b/xmake/rules/qt/load.lua
@@ -36,7 +36,11 @@ function _link(linkdirs, framework, qt_sdkver)
elseif is_plat("android") or is_plat("linux") then
debug_suffix = ""
end
- framework = "Qt" .. qt_sdkver:major() .. framework:sub(3) .. (is_mode("debug") and debug_suffix or "")
+ if qt_sdkver:ge("5.0") then
+ framework = "Qt" .. qt_sdkver:major() .. framework:sub(3) .. (is_mode("debug") and debug_suffix or "")
+ else -- for qt4.x, e.g. QtGui4.lib
+ framework = "Qt" .. framework:sub(3) .. (is_mode("debug") and debug_suffix or "") .. qt_sdkver:major()
+ end
if is_plat("android") then --> -lQt5Core_armeabi/-lQt5CoreDebug_armeabi for 5.14.x
local libinfo = find_library(framework .. "_" .. config.arch(), linkdirs)
if libinfo and libinfo.link then
@@ -77,10 +81,10 @@ function _add_plugins(target, plugins)
for name, plugin in pairs(plugins) do
target:values_add("qt.plugins", name)
if plugin.links then
- target:values_add("qt.links", unpack(table.wrap(plugin.links)))
+ target:values_add("qt.links", table.unpack(table.wrap(plugin.links)))
end
if plugin.linkdirs then
- target:values_add("qt.linkdirs", unpack(table.wrap(plugin.linkdirs)))
+ target:values_add("qt.linkdirs", table.unpack(table.wrap(plugin.linkdirs)))
end
end
end
diff --git a/xmake/rules/qt/moc/xmake.lua b/xmake/rules/qt/moc/xmake.lua
index 80ce37174..f12fcf217 100644
--- a/xmake/rules/qt/moc/xmake.lua
+++ b/xmake/rules/qt/moc/xmake.lua
@@ -32,6 +32,9 @@ rule("qt.moc")
if not os.isexec(moc) and qt.libexecdir then
moc = path.join(qt.libexecdir, is_host("windows") and "moc.exe" or "moc")
end
+ if not os.isexec(moc) and qt.libexecdir_host then
+ moc = path.join(qt.libexecdir_host, is_host("windows") and "moc.exe" or "moc")
+ end
assert(moc and os.isexec(moc), "moc not found!")
-- get c++ source file for moc
diff --git a/xmake/rules/qt/qrc/xmake.lua b/xmake/rules/qt/qrc/xmake.lua
index df416c2a9..64e37d2ab 100644
--- a/xmake/rules/qt/qrc/xmake.lua
+++ b/xmake/rules/qt/qrc/xmake.lua
@@ -29,6 +29,9 @@ rule("qt.qrc")
if not os.isexec(rcc) and qt.libexecdir then
rcc = path.join(qt.libexecdir, is_host("windows") and "rcc.exe" or "rcc")
end
+ if not os.isexec(rcc) and qt.libexecdir_host then
+ rcc = path.join(qt.libexecdir_host, is_host("windows") and "rcc.exe" or "rcc")
+ end
assert(os.isexec(rcc), "rcc not found!")
-- save rcc
diff --git a/xmake/rules/qt/ui/xmake.lua b/xmake/rules/qt/ui/xmake.lua
index dd377563b..2d02a134b 100644
--- a/xmake/rules/qt/ui/xmake.lua
+++ b/xmake/rules/qt/ui/xmake.lua
@@ -29,6 +29,9 @@ rule("qt.ui")
if not os.isexec(uic) and qt.libexecdir then
uic = path.join(qt.libexecdir, is_host("windows") and "uic.exe" or "uic")
end
+ if not os.isexec(uic) and qt.libexecdir_host then
+ uic = path.join(qt.libexecdir_host, is_host("windows") and "uic.exe" or "uic")
+ end
assert(uic and os.isexec(uic), "uic not found!")
-- add includedirs, @note we need create this directory first to suppress warning (file not found).
diff --git a/xmake/rules/qt/xmake.lua b/xmake/rules/qt/xmake.lua
index ed4deedb7..b26a458a5 100644
--- a/xmake/rules/qt/xmake.lua
+++ b/xmake/rules/qt/xmake.lua
@@ -87,7 +87,20 @@ rule("qt.widgetapp")
end)
on_config(function (target)
- import("load")(target, {gui = true, frameworks = {"QtGui", "QtWidgets", "QtCore"}})
+
+ -- get qt sdk version
+ local qt = target:data("qt")
+ local qt_sdkver = nil
+ if qt.sdkver then
+ import("core.base.semver")
+ qt_sdkver = semver.new(qt.sdkver)
+ end
+
+ local frameworks = {"QtGui", "QtWidgets", "QtCore"}
+ if qt_sdkver and qt_sdkver:lt("5.0") then
+ frameworks = {"QtGui", "QtCore"} -- qt4.x has not QtWidgets, it is in QtGui
+ end
+ import("load")(target, {gui = true, frameworks = frameworks})
end)
-- deploy application
@@ -124,9 +137,12 @@ rule("qt.widgetapp_static")
QtPlatformSupport = "QtPlatformCompositorSupport"
end
- -- laod some basic plugins and frameworks
+ -- load some basic plugins and frameworks
local plugins = {}
local frameworks = {"QtGui", "QtWidgets", "QtCore"}
+ if qt_sdkver and qt_sdkver:lt("5.0") then
+ frameworks = {"QtGui", "QtCore"} -- qt4.x has not QtWidgets, it is in QtGui
+ end
if target:is_plat("macosx") then
plugins.QCocoaIntegrationPlugin = {linkdirs = "plugins/platforms", links = {"qcocoa", "cups"}}
table.join2(frameworks, QtPlatformSupport, "QtWidgets")
@@ -195,7 +211,7 @@ rule("qt.quickapp_static")
QtPlatformSupport = "QtPlatformCompositorSupport"
end
- -- laod some basic plugins and frameworks
+ -- load some basic plugins and frameworks
local plugins = {}
local frameworks = {"QtGui", "QtQuick", "QtQml", "QtQmlModels", "QtCore", "QtNetwork"}
if target:is_plat("macosx") then
diff --git a/xmake/rules/rust/build/cxxbridge.lua b/xmake/rules/rust/build/cxxbridge.lua
new file mode 100644
index 000000000..1fc9b3778
--- /dev/null
+++ b/xmake/rules/rust/build/cxxbridge.lua
@@ -0,0 +1,50 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file cxxbridge.lua
+--
+
+-- imports
+import("core.base.option")
+import("lib.detect.find_tool")
+
+function main(target, batchcmds, sourcefile, opt)
+ local cxxbridge = assert(find_tool("cxxbridge"), "cxxbridge not found, please run `cargo install cxxbridge` to install it first!")
+
+ -- get c/c++ source file for cxxbridge
+ local headerfile = path.join(target:autogendir(), "rules", "cxxbridge", path.basename(sourcefile) .. ".rs.h")
+ local sourcefile_cx = path.join(target:autogendir(), "rules", "cxxbridge", path.basename(sourcefile) .. ".rs.cc")
+
+ -- add includedirs
+ target:add("includedirs", path.directory(headerfile))
+
+ -- add objectfile
+ local objectfile = target:objectfile(sourcefile_cx)
+ table.insert(target:objectfiles(), objectfile)
+
+ -- add commands
+ batchcmds:show_progress(opt.progress, "${color.build.object}compiling.cxxbridge %s", sourcefile)
+ batchcmds:mkdir(path.directory(sourcefile_cx))
+ batchcmds:vrunv(cxxbridge.program, {sourcefile}, {stdout = sourcefile_cx})
+ batchcmds:vrunv(cxxbridge.program, {sourcefile, "--header"}, {stdout = headerfile})
+ batchcmds:compile(sourcefile_cx, objectfile)
+
+ -- add deps
+ batchcmds:add_depfiles(sourcefile)
+ batchcmds:set_depmtime(os.mtime(objectfile))
+ batchcmds:set_depcache(target:dependfile(objectfile))
+end
diff --git a/xmake/rules/rust/build/target.lua b/xmake/rules/rust/build/target.lua
index 67917ad29..5f0167693 100644
--- a/xmake/rules/rust/build/target.lua
+++ b/xmake/rules/rust/build/target.lua
@@ -21,19 +21,13 @@
-- imports
import("core.base.option")
import("core.base.hashset")
-import("core.theme.theme")
import("core.tool.compiler")
import("core.project.depend")
+import("utils.progress")
-- build the source files
function build_sourcefiles(target, sourcebatch, opt)
- -- is verbose?
- local verbose = option.get("verbose")
-
- -- get progress range
- local progress = assert(opt.progress, "no progress!")
-
-- get the target file
local targetfile = target:targetfile()
@@ -60,17 +54,10 @@ function build_sourcefiles(target, sourcebatch, opt)
end
-- trace progress into
- cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress)
- if verbose then
- cprint("${dim color.build.target}linking.$(mode) %s", path.filename(targetfile))
- else
- cprint("${color.build.target}linking.$(mode) %s", path.filename(targetfile))
- end
+ progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", path.filename(targetfile))
-- trace verbose info
- if verbose then
- print(compinst:buildcmd(sourcefiles, targetfile, {target = target, compflags = compflags}))
- end
+ vprint(compinst:buildcmd(sourcefiles, targetfile, {target = target, compflags = compflags}))
-- flush io buffer to update progress info
io.flush()
@@ -89,10 +76,11 @@ end
function main(target, opt)
-- @note only support one source kind!
- for _, sourcebatch in pairs(target:sourcebatches()) do
- if sourcebatch.sourcekind == "rc" then
+ local sourcebatches = target:sourcebatches()
+ if sourcebatches then
+ local sourcebatch = sourcebatches["rust.build"]
+ if sourcebatch then
build_sourcefiles(target, sourcebatch, opt)
- break
end
end
end
diff --git a/xmake/rules/rust/xmake.lua b/xmake/rules/rust/xmake.lua
index a8ccae429..e31e2f046 100644
--- a/xmake/rules/rust/xmake.lua
+++ b/xmake/rules/rust/xmake.lua
@@ -18,16 +18,52 @@
-- @file xmake.lua
--
--- define rule: rust.build
+-- generate bridge.rs.cc/h to call rust library in c++ code
+-- @see https://cxx.rs/build/other.html
+rule("rust.cxxbridge")
+ set_extensions(".rsx")
+ on_load(function (target)
+ if not target:get("languages") then
+ target:set("languages", "c++11")
+ end
+ end)
+ before_buildcmd_file("build.cxxbridge")
+
rule("rust.build")
set_sourcekinds("rc")
+ on_load(function (target)
+ -- set cratetype
+ local cratetype = target:values("rust.cratetype")
+ if cratetype == "staticlib" then
+ assert(target:is_static(), "target(%s) must be static kind for cratetype(staticlib)!", target:name())
+ target:add("arflags", "--crate-type=staticlib")
+ target:data_set("inherit.links.exportlinks", false)
+ elseif cratetype == "cdylib" then
+ assert(target:is_shared(), "target(%s) must be shared kind for cratetype(cdylib)!", target:name())
+ target:add("shflags", "--crate-type=cdylib")
+ target:add("shflags", "-C prefer-dynamic")
+ elseif target:is_static() then
+ target:set("extension", ".rlib")
+ target:add("arflags", "--crate-type=lib")
+ target:data_set("inherit.links.deplink", false)
+ elseif target:is_shared() then
+ target:add("shflags", "--crate-type=dylib")
+ -- fix cannot satisfy dependencies so `std` only shows up once
+ -- https://github.com/rust-lang/rust/issues/19680
+ --
+ -- but it will link dynamic @rpath/libstd-xxx.dylib,
+ -- so we can no longer modify and set other rpath paths
+ target:add("shflags", "-C prefer-dynamic")
+ elseif target:is_binary() then
+ target:add("ldflags", "--crate-type=bin")
+ end
+
+ -- set edition
+ local edition = target:values("rust.edition") or "2018"
+ target:add("rcflags", "--edition", edition, {force = true})
+ end)
on_build("build.target")
--- define rule: rust
rule("rust")
-
- -- add build rules
add_deps("rust.build")
-
- -- inherit links and linkdirs of all dependent targets by default
add_deps("utils.inherit.links")
diff --git a/xmake/rules/swig/build_module_file.lua b/xmake/rules/swig/build_module_file.lua
new file mode 100644
index 000000000..42c9d9238
--- /dev/null
+++ b/xmake/rules/swig/build_module_file.lua
@@ -0,0 +1,55 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file build_module_file.lua
+--
+
+-- imports
+import("lib.detect.find_tool")
+
+function main(target, batchcmds, sourcefile, opt)
+
+ -- get swig
+ opt = opt or {}
+ local swig = assert(find_tool("swig"), "swig not found!")
+ local sourcefile_cx = path.join(target:autogendir(), "rules", "swig", path.basename(sourcefile) .. (opt.sourcekind == "cxx" and ".cpp" or ".c"))
+
+ -- add objectfile
+ local objectfile = target:objectfile(sourcefile_cx)
+ table.insert(target:objectfiles(), objectfile)
+
+ -- add commands
+ local moduletype = assert(target:data("swig.moduletype"), "swig.moduletype not found!")
+ local argv = {"-" .. moduletype, "-o", sourcefile_cx}
+ if opt.sourcekind == "cxx" then
+ table.insert(argv, "-c++")
+ end
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig.swigflags then
+ table.join2(argv, fileconfig.swigflags)
+ end
+ table.insert(argv, sourcefile)
+ batchcmds:show_progress(opt.progress, "${color.build.object}compiling.swig.%s %s", moduletype, sourcefile)
+ batchcmds:mkdir(path.directory(sourcefile_cx))
+ batchcmds:vrunv(swig.program, argv)
+ batchcmds:compile(sourcefile_cx, objectfile)
+
+ -- add deps
+ batchcmds:add_depfiles(sourcefile)
+ batchcmds:set_depmtime(os.mtime(objectfile))
+ batchcmds:set_depcache(target:dependfile(objectfile))
+end
diff --git a/xmake/rules/swig/xmake.lua b/xmake/rules/swig/xmake.lua
new file mode 100644
index 000000000..c0387a940
--- /dev/null
+++ b/xmake/rules/swig/xmake.lua
@@ -0,0 +1,98 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- references:
+--
+-- https://github.com/xmake-io/xmake/issues/1622
+-- http://www.swig.org/Doc4.0/SWIGDocumentation.html#Introduction_nn4
+--
+
+rule("swig.base")
+ on_load(function (target)
+ target:set("kind", "shared")
+ local moduletype = target:extraconf("rules", "swig.c", "moduletype") or target:extraconf("rules", "swig.cpp", "moduletype")
+ if moduletype == "python" then
+ target:set("prefixname", "_")
+ local soabi = target:extraconf("rules", "swig.c", "soabi") or target:extraconf("rules", "swig.cpp", "soabi")
+ if soabi then
+ import("lib.detect.find_tool")
+ local python = assert(find_tool("python3"), "python not found!")
+ local result = try { function() return os.iorunv(python.program, {"-c", "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"}) end}
+ if result then
+ result = result:trim()
+ if result ~= "None" then
+ target:set("extension", result)
+ end
+ end
+ else
+ if target:is_plat("windows") then
+ target:set("extension", ".pyd")
+ end
+ end
+ elseif moduletype == "lua" then
+ target:set("prefixname", "")
+ if not target:is_plat("windows") then
+ target:set("extension", ".so")
+ end
+ else
+ raise("unknown swig module type, please use `add_rules(\"swig.c\", {moduletype = \"python\"})` to set it!")
+ end
+ local scriptfiles = {}
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ if sourcebatch.rulename:startswith("swig.") then
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local scriptdir
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig then
+ scriptdir = fileconfig.scriptdir
+ end
+ local scriptfile = path.join(target:autogendir(), "rules", "swig", path.basename(sourcefile))
+ if moduletype == "python" then
+ scriptfile = scriptfile .. ".py"
+ elseif moduletype == "lua" then
+ scriptfile = scriptfile .. ".lua"
+ end
+ table.insert(scriptfiles, scriptfile)
+ if scriptdir then
+ target:add("installfiles", scriptfile, {prefixdir = scriptdir})
+ end
+ end
+ end
+ end
+ -- for custom on_install/after_install, user can use it to install them
+ target:data_set("swig.scriptfiles", scriptfiles)
+ target:data_set("swig.moduletype", moduletype)
+ end)
+
+rule("swig.c")
+ set_extensions(".i")
+ add_deps("swig.base", "c.build")
+ on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
+ import("build_module_file")(target, batchcmds, sourcefile, table.join({sourcekind = "cc"}, opt))
+ end)
+
+rule("swig.cpp")
+ set_extensions(".i")
+ add_deps("swig.base", "c++.build")
+ on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
+ import("build_module_file")(target, batchcmds, sourcefile, table.join({sourcekind = "cxx"}, opt))
+ end)
+
+
diff --git a/xmake/rules/utils/bin2c/xmake.lua b/xmake/rules/utils/bin2c/xmake.lua
index 12db55192..77f81125c 100644
--- a/xmake/rules/utils/bin2c/xmake.lua
+++ b/xmake/rules/utils/bin2c/xmake.lua
@@ -20,10 +20,17 @@
rule("utils.bin2c")
set_extensions(".bin")
+ on_load(function (target)
+ local headerdir = path.join(target:autogendir(), "rules", "utils", "bin2c")
+ if not os.isdir(headerdir) then
+ os.mkdir(headerdir)
+ end
+ target:add("includedirs", headerdir)
+ end)
before_buildcmd_file(function (target, batchcmds, sourcefile_bin, opt)
-- get header file
- local headerdir = path.join(target:autogendir(), "rules", "c++", "bin2c")
+ local headerdir = path.join(target:autogendir(), "rules", "utils", "bin2c")
local headerfile = path.join(headerdir, path.filename(sourcefile_bin) .. ".h")
target:add("includedirs", headerdir)
@@ -36,7 +43,7 @@ rule("utils.bin2c")
table.insert(argv, "-w")
table.insert(argv, tostring(linewidth))
end
- batchcmds:vrunv(os.programfile(), argv)
+ batchcmds:vrunv(os.programfile(), argv, {envs = {XMAKE_SKIP_HISTORY = "y"}})
-- add deps
batchcmds:add_depfiles(sourcefile_bin)
diff --git a/xmake/rules/utils/glsl2spv/xmake.lua b/xmake/rules/utils/glsl2spv/xmake.lua
new file mode 100644
index 000000000..faf655ec6
--- /dev/null
+++ b/xmake/rules/utils/glsl2spv/xmake.lua
@@ -0,0 +1,90 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- compile glsl shader to spirv file, .spv
+--
+-- e.g.
+-- compile *.vert/*.frag to *.vert.spv/*.frag.spv files
+-- add_rules("utils.glsl2spv", {outputdir = "build"})
+--
+-- compile *.vert/*.frag and generate binary c header files
+-- add_rules("utils.glsl2spv", {bin2c = true})
+--
+-- in c code:
+-- static unsigned char g_test_frag_spv_data[] = {
+-- #include "test.frag.spv.h"
+-- };
+--
+--
+rule("utils.glsl2spv")
+ set_extensions(".vert", ".frag", ".tesc", ".tese", ".geom", ".comp", ".glsl")
+ on_load(function (target)
+ local is_bin2c = target:extraconf("rules", "utils.glsl2spv", "bin2c")
+ if is_bin2c then
+ local headerdir = path.join(target:autogendir(), "rules", "utils", "glsl2spv")
+ if not os.isdir(headerdir) then
+ os.mkdir(headerdir)
+ end
+ target:add("includedirs", headerdir)
+ end
+ end)
+ before_buildcmd_file(function (target, batchcmds, sourcefile_glsl, opt)
+ import("lib.detect.find_tool")
+
+ -- get glslangValidator
+ local glslc
+ local glslangValidator = find_tool("glslangValidator")
+ if not glslangValidator then
+ glslc = find_tool("glslc")
+ end
+ assert(glslangValidator or glslc, "glslangValidator or glslc not found!")
+
+ -- glsl to spv
+ local outputdir = target:extraconf("rules", "utils.glsl2spv", "outputdir") or path.join(target:autogendir(), "rules", "utils", "glsl2spv")
+ local spvfilepath = path.join(outputdir, path.filename(sourcefile_glsl) .. ".spv")
+ batchcmds:show_progress(opt.progress, "${color.build.object}generating.glsl2spv %s", sourcefile_glsl)
+ batchcmds:mkdir(outputdir)
+ if glslangValidator then
+ batchcmds:vrunv(glslangValidator.program, {"-V", "-o", spvfilepath, sourcefile_glsl})
+ else
+ batchcmds:vrunv(glslc.program, {"-o", spvfilepath, sourcefile_glsl})
+ end
+
+ -- do bin2c
+ local outputfile = spvfilepath
+ local is_bin2c = target:extraconf("rules", "utils.glsl2spv", "bin2c")
+ if is_bin2c then
+ -- get header file
+ local headerdir = outputdir
+ local headerfile = path.join(headerdir, path.filename(spvfilepath) .. ".h")
+ target:add("includedirs", headerdir)
+ outputfile = headerfile
+
+ -- add commands
+ local argv = {"lua", "private.utils.bin2c", "--nozeroend", "-i", spvfilepath, "-o", headerfile}
+ batchcmds:vrunv(os.programfile(), argv, {envs = {XMAKE_SKIP_HISTORY = "y"}})
+ end
+
+ -- add deps
+ batchcmds:add_depfiles(sourcefile_glsl)
+ batchcmds:set_depmtime(os.mtime(outputfile))
+ batchcmds:set_depcache(target:dependfile(outputfile))
+ end)
+
diff --git a/xmake/rules/utils/inherit_links/inherit_links.lua b/xmake/rules/utils/inherit_links/inherit_links.lua
index 97c585ded..79c737503 100644
--- a/xmake/rules/utils/inherit_links/inherit_links.lua
+++ b/xmake/rules/utils/inherit_links/inherit_links.lua
@@ -46,7 +46,6 @@ function _add_export_value(target, name, value)
end
end
--- main entry
function main(target)
-- disable inherit.links for `add_deps()`?
@@ -59,12 +58,15 @@ function main(target)
if targetkind == "shared" or targetkind == "static" then
local targetfile = target:targetfile()
- -- we need move target link to head
- _add_export_value(target, "links", target:linkname())
- local links = target:get("links", {rawref = true})
- if links and type(links) == "table" and #links > 1 then
- table.insert(links, 1, links[#links])
- table.remove(links, #links)
+ -- rust maybe will disable inherit links, only inherit linkdirs
+ if target:data("inherit.links.deplink") ~= false then
+ -- we need move target link to head
+ _add_export_value(target, "links", target:linkname())
+ local links = target:get("links", {rawref = true})
+ if links and type(links) == "table" and #links > 1 then
+ table.insert(links, 1, links[#links])
+ table.remove(links, #links)
+ end
end
_add_export_value(target, "linkdirs", path.directory(targetfile))
@@ -78,11 +80,13 @@ function main(target)
-- @note we only export links for static target,
-- and we need pass `{public = true}` to add_packages/add_links/... to export it if want to export links for shared target
--
- if targetkind == "static" then
- for _, name in ipairs({"frameworkdirs", "frameworks", "linkdirs", "links", "syslinks"}) do
- local values = _get_values_from_target(target, name)
- if values and #values > 0 then
- target:add(name, values, {public = true})
+ if target:data("inherit.links.exportlinks") ~= false then
+ if targetkind == "static" then
+ for _, name in ipairs({"rpathdirs", "frameworkdirs", "frameworks", "linkdirs", "links", "syslinks"}) do
+ local values = _get_values_from_target(target, name)
+ if values and #values > 0 then
+ target:add(name, values, {public = true})
+ end
end
end
end
diff --git a/xmake/rules/utils/install_importfiles/xmake.lua b/xmake/rules/utils/install_importfiles/xmake.lua
index 45e6616f8..848f215e1 100644
--- a/xmake/rules/utils/install_importfiles/xmake.lua
+++ b/xmake/rules/utils/install_importfiles/xmake.lua
@@ -21,7 +21,9 @@
-- install pkg-config/*.pc import files
rule("utils.install.pkgconfig_importfiles")
after_install(function (target, opt)
- import("target.action.install.pkgconfig_importfiles")(target, opt)
+ opt = opt or {}
+ local filename = target:extraconf("rules", "utils.install.pkgconfig_importfiles", "filename")
+ import("target.action.install.pkgconfig_importfiles")(target, table.join(opt, {filename = filename}))
end)
-- install *.cmake import files
diff --git a/xmake/rules/utils/merge_archive/merge_archive.lua b/xmake/rules/utils/merge_archive/merge_archive.lua
index 96069befb..02d572afc 100644
--- a/xmake/rules/utils/merge_archive/merge_archive.lua
+++ b/xmake/rules/utils/merge_archive/merge_archive.lua
@@ -23,7 +23,7 @@ import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
import("core.project.target", {alias = "project_target"})
-import("private.utils.progress")
+import("utils.progress")
import("core.tool.toolchain")
import("private.tools.vstool")
@@ -93,11 +93,12 @@ end
-- do extract
function _extract(target, libraryfile, objectdir)
- local program, toolname = target:tool("ex")
+ local program, toolname = target:tool("ar")
if program and toolname then
if toolname:find("ar") then
_extract_for_ar(program, libraryfile, objectdir)
- elseif toolname == "lib" then
+ elseif toolname == "link" then
+ program = program:replace("link.exe", "lib.exe", {plain = true})
_extract_for_msvclib(program, libraryfile, objectdir)
end
else
diff --git a/xmake/rules/utils/merge_archive/xmake.lua b/xmake/rules/utils/merge_archive/xmake.lua
index 6d57f55bb..fd7805d8b 100644
--- a/xmake/rules/utils/merge_archive/xmake.lua
+++ b/xmake/rules/utils/merge_archive/xmake.lua
@@ -18,12 +18,32 @@
-- @file xmake.lua
--
--- define rule: utils.merge.archive
rule("utils.merge.archive")
-
- -- set extensions
set_extensions(".a", ".lib")
-
- -- on build file
on_build_files("merge_archive")
+ after_link(function (target, opt)
+ if target:policy("build.merge_archive") and target:is_static() then
+ import("utils.archive.merge_staticlib")
+ import("core.project.depend")
+ import("utils.progress")
+ local libraryfiles = {}
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:is_static() then
+ table.insert(libraryfiles, dep:targetfile())
+ end
+ end
+ if #libraryfiles > 0 then
+ table.insert(libraryfiles, target:targetfile())
+ end
+ depend.on_changed(function ()
+ progress.show(opt.progress, "${color.build.target}merging.$(mode) %s", path.filename(target:targetfile()))
+ if #libraryfiles > 0 then
+ local tmpfile = os.tmpfile() .. path.extension(target:targetfile())
+ merge_staticlib(target, tmpfile, libraryfiles)
+ os.cp(tmpfile, target:targetfile())
+ os.rm(tmpfile)
+ end
+ end, {dependfile = target:dependfile(target:targetfile() .. ".merge_archive"), files = libraryfiles})
+ end
+ end)
diff --git a/xmake/rules/utils/merge_object/xmake.lua b/xmake/rules/utils/merge_object/xmake.lua
index 167e9013e..8bebb5f5c 100644
--- a/xmake/rules/utils/merge_object/xmake.lua
+++ b/xmake/rules/utils/merge_object/xmake.lua
@@ -31,7 +31,7 @@ rule("utils.merge.object")
import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
- import("private.utils.progress")
+ import("utils.progress")
-- get object file
local objectfile = target:objectfile(sourcefile_obj)
diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua
index 1a40e9820..f8247a878 100644
--- a/xmake/rules/utils/symbols/export_all/export_all.lua
+++ b/xmake/rules/utils/symbols/export_all/export_all.lua
@@ -24,7 +24,7 @@ import("core.tool.toolchain")
import("core.base.option")
import("core.base.hashset")
import("core.project.depend")
-import("private.utils.progress")
+import("utils.progress")
-- export all symbols for dynamic library
function main (target, opt)
@@ -56,8 +56,9 @@ function main (target, opt)
local objectsymbols = try { function () return os.iorunv(dumpbin.program, {"/symbols", "/nologo", objectfile}) end }
if objectsymbols then
for _, line in ipairs(objectsymbols:split('\n', {plain = true})) do
+ -- https://docs.microsoft.com/en-us/cpp/build/reference/symbols
-- 008 00000000 SECT3 notype () External | add
- if line:find("External") then
+ if line:find("External") and not line:find("UNDEF") then
local symbol = line:match(".*External%s+| (.*)")
if symbol then
symbol = symbol:split('%s')[1]
diff --git a/xmake/rules/utils/symbols/export_all/xmake.lua b/xmake/rules/utils/symbols/export_all/xmake.lua
index f804e3c3e..b808d63a9 100644
--- a/xmake/rules/utils/symbols/export_all/xmake.lua
+++ b/xmake/rules/utils/symbols/export_all/xmake.lua
@@ -26,7 +26,7 @@
-- @see https://github.com/xmake-io/xmake/issues/1123
--
rule("utils.symbols.export_all")
- before_load(function (target)
+ on_load(function (target)
-- @note it only supports windows/dll now
assert(target:is_shared(), 'rule("utils.symbols.export_all"): only for shared target(%s)!', target:name())
if target:is_plat("windows") then
diff --git a/xmake/rules/utils/symbols/extract/xmake.lua b/xmake/rules/utils/symbols/extract/xmake.lua
index f78cab808..dd1f3a1df 100644
--- a/xmake/rules/utils/symbols/extract/xmake.lua
+++ b/xmake/rules/utils/symbols/extract/xmake.lua
@@ -46,7 +46,7 @@ rule("utils.symbols.extract")
import("core.theme.theme")
import("core.project.depend")
import("core.platform.platform")
- import("private.utils.progress")
+ import("utils.progress")
-- get strip
local strip = target:tool("strip")
diff --git a/xmake/rules/vala/xmake.lua b/xmake/rules/vala/xmake.lua
index a2ce76937..6c3d36213 100644
--- a/xmake/rules/vala/xmake.lua
+++ b/xmake/rules/vala/xmake.lua
@@ -18,7 +18,7 @@
-- @file xmake.lua
--
-rule("vala")
+rule("vala.build")
set_extensions(".vala")
on_load(function (target)
-- only vala source files? we need patch c source kind for linker
@@ -26,6 +26,37 @@ rule("vala")
if #sourcekinds == 0 then
table.insert(sourcekinds, "cc")
end
+
+ -- we disable to build across targets in parallel, because the source files may depend on other target modules
+ target:set("policy", "build.across_targets_in_parallel", false)
+
+ -- get vapi file
+ local vapifile = target:data("vala.vapifile")
+ if not vapifile then
+ local vapiname = target:values("vala.vapi")
+ if vapiname then
+ vapifile = path.join(target:targetdir(), vapiname)
+ else
+ vapifile = path.join(target:targetdir(), target:name() .. ".vapi")
+ end
+ target:data_set("vala.vapifile", vapifile)
+ end
+
+ -- get header file
+ local headerfile = target:data("vala.headerfile")
+ if not headerfile then
+ local headername = target:values("vala.header")
+ if headername then
+ headerfile = path.join(target:targetdir(), headername)
+ else
+ headerfile = path.join(target:targetdir(), target:name() .. ".h")
+ end
+ target:data_set("vala.headerfile", headerfile)
+ end
+ if headerfile then
+ target:add("headerfiles", headerfile)
+ target:add("sysincludedirs", path.directory(headerfile), {public = true})
+ end
end)
before_buildcmd_file(function (target, batchcmds, sourcefile_vala, opt)
@@ -52,6 +83,34 @@ rule("vala")
table.insert(argv, package)
end
end
+ if target:is_binary() then
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:is_shared() or dep:is_static() then
+ local vapifile = dep:data("vala.vapifile")
+ if vapifile then
+ table.join2(argv, vapifile)
+ end
+ end
+ end
+ else
+ local vapifile = target:data("vala.vapifile")
+ if vapifile then
+ table.insert(argv, "--vapi=" .. vapifile)
+ end
+ local headerfile = target:data("vala.headerfile")
+ if headerfile then
+ table.insert(argv, "-H")
+ table.insert(argv, headerfile)
+ end
+ end
+ local vapidir = target:data("vala.vapidir")
+ if vapidir then
+ table.insert(argv, "--vapidir=" .. vapidir)
+ end
+ local valaflags = target:data("vala.flags")
+ if valaflags then
+ table.join2(argv, valaflags)
+ end
table.insert(argv, sourcefile_vala)
batchcmds:vrunv(valac.program, argv)
batchcmds:compile(sourcefile_c, objectfile)
@@ -62,3 +121,54 @@ rule("vala")
batchcmds:set_depcache(target:dependfile(objectfile))
end)
+ after_install(function (target)
+ if target:is_shared() or target:is_static() then
+ local vapifile = target:data("vala.vapifile")
+ if vapifile then
+ local installdir = target:installdir()
+ if installdir then
+ local sharedir = path.join(installdir, "share")
+ os.mkdir(sharedir)
+ os.vcp(vapifile, sharedir)
+ end
+ end
+ end
+ end)
+
+ after_uninstall(function (target)
+ if target:is_shared() or target:is_static() then
+ local vapifile = target:data("vala.vapifile")
+ if vapifile then
+ local installdir = target:installdir()
+ if installdir then
+ os.rm(path.join(installdir, "share", path.filename(vapifile)))
+ end
+ end
+ end
+ end)
+
+rule("vala")
+
+ -- add build rules
+ add_deps("vala.build")
+
+ -- set compiler runtime, e.g. vs runtime
+ add_deps("utils.compiler.runtime")
+
+ -- inherit links and linkdirs of all dependent targets by default
+ add_deps("utils.inherit.links")
+
+ -- support `add_files("src/*.o")` and `add_files("src/*.a")` to merge object and archive files to target
+ add_deps("utils.merge.object", "utils.merge.archive")
+
+ -- we attempt to extract symbols to the independent file and
+ -- strip self-target binary if `set_symbols("debug")` and `set_strip("all")` are enabled
+ add_deps("utils.symbols.extract")
+
+ -- check targets
+ add_deps("utils.check.targets")
+
+ -- check licenses
+ add_deps("utils.check.licenses")
+
+
diff --git a/xmake/rules/wdk/env/xmake.lua b/xmake/rules/wdk/env/xmake.lua
index 6b7690933..a9089dc5e 100644
--- a/xmake/rules/wdk/env/xmake.lua
+++ b/xmake/rules/wdk/env/xmake.lua
@@ -22,7 +22,7 @@
rule("wdk.env")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("os.winver", {alias = "os_winver"})
diff --git a/xmake/rules/wdk/inf/xmake.lua b/xmake/rules/wdk/inf/xmake.lua
index fe060a10a..354fbc5a7 100644
--- a/xmake/rules/wdk/inf/xmake.lua
+++ b/xmake/rules/wdk/inf/xmake.lua
@@ -28,7 +28,7 @@ rule("wdk.inf")
set_extensions(".inf", ".inx")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
@@ -54,7 +54,7 @@ rule("wdk.inf")
import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
- import("private.utils.progress")
+ import("utils.progress")
-- the target file
local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".inf")
diff --git a/xmake/rules/wdk/man/xmake.lua b/xmake/rules/wdk/man/xmake.lua
index 25cce9f34..c5219aa56 100644
--- a/xmake/rules/wdk/man/xmake.lua
+++ b/xmake/rules/wdk/man/xmake.lua
@@ -28,7 +28,7 @@ rule("wdk.man")
set_extensions(".man")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
@@ -57,7 +57,7 @@ rule("wdk.man")
import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
- import("private.utils.progress")
+ import("utils.progress")
-- get ctrpp
local ctrpp = target:data("wdk.ctrpp")
diff --git a/xmake/rules/wdk/mc/xmake.lua b/xmake/rules/wdk/mc/xmake.lua
index 32653dfc2..689c9786c 100644
--- a/xmake/rules/wdk/mc/xmake.lua
+++ b/xmake/rules/wdk/mc/xmake.lua
@@ -28,7 +28,7 @@ rule("wdk.mc")
set_extensions(".mc")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
@@ -57,7 +57,7 @@ rule("wdk.mc")
import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
- import("private.utils.progress")
+ import("utils.progress")
-- get mc
local mc = target:data("wdk.mc")
diff --git a/xmake/rules/wdk/mof/xmake.lua b/xmake/rules/wdk/mof/xmake.lua
index 319eec5d7..a1a2a0366 100644
--- a/xmake/rules/wdk/mof/xmake.lua
+++ b/xmake/rules/wdk/mof/xmake.lua
@@ -28,7 +28,7 @@ rule("wdk.mof")
set_extensions(".mof")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
@@ -73,7 +73,7 @@ rule("wdk.mof")
import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
- import("private.utils.progress")
+ import("utils.progress")
-- get mofcomp
local mofcomp = target:data("wdk.mofcomp")
diff --git a/xmake/rules/wdk/sign/xmake.lua b/xmake/rules/wdk/sign/xmake.lua
index 7dcc28785..6be72e7b3 100644
--- a/xmake/rules/wdk/sign/xmake.lua
+++ b/xmake/rules/wdk/sign/xmake.lua
@@ -34,7 +34,7 @@ rule("wdk.sign")
add_deps("wdk.env")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
@@ -93,7 +93,7 @@ rule("wdk.sign")
import("core.project.config")
import("core.project.depend")
import("lib.detect.find_file")
- import("private.utils.progress")
+ import("utils.progress")
-- need build this object?
local tempfile = os.tmpfile(target:targetfile())
diff --git a/xmake/rules/wdk/tracewpp/xmake.lua b/xmake/rules/wdk/tracewpp/xmake.lua
index 0c49bf5d0..75f4f37ef 100644
--- a/xmake/rules/wdk/tracewpp/xmake.lua
+++ b/xmake/rules/wdk/tracewpp/xmake.lua
@@ -25,7 +25,7 @@ rule("wdk.tracewpp")
add_deps("wdk.env")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
@@ -57,7 +57,7 @@ rule("wdk.tracewpp")
import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
- import("private.utils.progress")
+ import("utils.progress")
-- get tracewpp
local tracewpp = target:data("wdk.tracewpp")
diff --git a/xmake/rules/winsdk/dotnet/xmake.lua b/xmake/rules/winsdk/dotnet/xmake.lua
index 5274f040a..1cfef7b58 100644
--- a/xmake/rules/winsdk/dotnet/xmake.lua
+++ b/xmake/rules/winsdk/dotnet/xmake.lua
@@ -22,7 +22,7 @@
rule("win.sdk.dotnet")
-- before load
- before_load(function (target)
+ on_load(function (target)
-- imports
import("core.project.config")
diff --git a/xmake/rules/winsdk/mfc/env/xmake.lua b/xmake/rules/winsdk/mfc/env/xmake.lua
index f603ebfe2..f553618b5 100644
--- a/xmake/rules/winsdk/mfc/env/xmake.lua
+++ b/xmake/rules/winsdk/mfc/env/xmake.lua
@@ -22,5 +22,5 @@
rule("win.sdk.mfc.env")
-- TODO: before load need check of vs's minverion, if defined
- before_load(function (target)
+ on_load(function (target)
end)
diff --git a/xmake/rules/winsdk/xmake.lua b/xmake/rules/winsdk/xmake.lua
index 0a3b105cc..297dfda75 100644
--- a/xmake/rules/winsdk/xmake.lua
+++ b/xmake/rules/winsdk/xmake.lua
@@ -27,7 +27,7 @@ rule("win.sdk.resource")
rule("win.sdk.application")
-- before load
- before_load(function (target)
+ on_load(function (target)
target:set("kind", "binary")
end)
diff --git a/xmake/rules/xcode/application/build.lua b/xmake/rules/xcode/application/build.lua
index 786f5da89..a4862ae86 100644
--- a/xmake/rules/xcode/application/build.lua
+++ b/xmake/rules/xcode/application/build.lua
@@ -23,7 +23,7 @@ import("core.base.option")
import("core.theme.theme")
import("core.project.depend")
import("private.tools.codesign")
-import("private.utils.progress")
+import("utils.progress")
-- main entry
function main (target, opt)
diff --git a/xmake/rules/xcode/application/load.lua b/xmake/rules/xcode/application/load.lua
index 3071ccd58..354aa5b0c 100644
--- a/xmake/rules/xcode/application/load.lua
+++ b/xmake/rules/xcode/application/load.lua
@@ -54,15 +54,4 @@ function main (target)
-- register clean files for `xmake clean`
target:add("cleanfiles", bundledir)
-
- -- depend xcode.framework? we need disable `build.across_targets_in_parallel` policy
- local across_targets_in_parallel
- for _, dep in ipairs(target:orderdeps()) do
- if dep:rule("xcode.framework") then
- across_targets_in_parallel = false
- end
- end
- if across_targets_in_parallel ~= nil then
- target:set("policy", "build.across_targets_in_parallel", across_targets_in_parallel)
- end
end
diff --git a/xmake/rules/xcode/application/run.lua b/xmake/rules/xcode/application/run.lua
index e92397a29..0e0663207 100644
--- a/xmake/rules/xcode/application/run.lua
+++ b/xmake/rules/xcode/application/run.lua
@@ -40,10 +40,10 @@ function _run_on_macosx(target, opt)
-- add run environments
local addrunenvs, setrunenvs = make_runenvs(target)
for name, values in pairs(addrunenvs) do
- os.addenv(name, unpack(table.wrap(values)))
+ os.addenv(name, table.unpack(table.wrap(values)))
end
for name, value in pairs(setrunenvs) do
- os.setenv(name, unpack(table.wrap(value)))
+ os.setenv(name, table.unpack(table.wrap(value)))
end
-- debugging?
diff --git a/xmake/rules/xcode/application/xmake.lua b/xmake/rules/xcode/application/xmake.lua
index 5984bbb55..d328262c0 100644
--- a/xmake/rules/xcode/application/xmake.lua
+++ b/xmake/rules/xcode/application/xmake.lua
@@ -21,11 +21,24 @@
-- define rule: xcode application
rule("xcode.application")
- -- support add_files("Info.plist", "*.storyboard", "*.xcassets")
- add_deps("xcode.info_plist", "xcode.storyboard", "xcode.xcassets")
+ -- support add_files("Info.plist", "*.storyboard", "*.xcassets", "*.metal")
+ add_deps("xcode.info_plist", "xcode.storyboard", "xcode.xcassets", "xcode.metal")
-- we must set kind before target.on_load(), may we will use target in on_load()
- before_load("load")
+ on_load("load")
+
+ -- depend xcode.framework? we need disable `build.across_targets_in_parallel` policy
+ after_load(function (target)
+ local across_targets_in_parallel
+ for _, dep in ipairs(target:orderdeps()) do
+ if dep:rule("xcode.framework") then
+ across_targets_in_parallel = false
+ end
+ end
+ if across_targets_in_parallel ~= nil then
+ target:set("policy", "build.across_targets_in_parallel", across_targets_in_parallel)
+ end
+ end)
-- build *.app
after_build("build")
diff --git a/xmake/rules/xcode/bundle/xmake.lua b/xmake/rules/xcode/bundle/xmake.lua
index bd8e4329e..322a42418 100644
--- a/xmake/rules/xcode/bundle/xmake.lua
+++ b/xmake/rules/xcode/bundle/xmake.lua
@@ -25,7 +25,7 @@ rule("xcode.bundle")
add_deps("xcode.info_plist")
-- we must set kind before target.on_load(), may we will use target in on_load()
- before_load(function (target)
+ on_load(function (target)
-- get bundle directory
local targetdir = target:targetdir()
@@ -60,7 +60,7 @@ rule("xcode.bundle")
import("core.theme.theme")
import("core.project.depend")
import("private.tools.codesign")
- import("private.utils.progress")
+ import("utils.progress")
-- get bundle and resources directory
local bundledir = path.absolute(target:data("xcode.bundle.rootdir"))
diff --git a/xmake/rules/xcode/framework/xmake.lua b/xmake/rules/xcode/framework/xmake.lua
index b112dcaf1..de7d7c93c 100644
--- a/xmake/rules/xcode/framework/xmake.lua
+++ b/xmake/rules/xcode/framework/xmake.lua
@@ -25,7 +25,7 @@ rule("xcode.framework")
add_deps("xcode.info_plist")
-- we must set kind before target.on_load(), may we will use target in on_load()
- before_load(function (target)
+ on_load(function (target)
-- get framework directory
local targetdir = target:targetdir()
@@ -85,7 +85,7 @@ rule("xcode.framework")
import("core.theme.theme")
import("core.project.depend")
import("private.tools.codesign")
- import("private.utils.progress")
+ import("utils.progress")
-- get framework directory
local bundledir = path.absolute(target:data("xcode.bundle.rootdir"))
diff --git a/xmake/rules/xcode/info_plist/xmake.lua b/xmake/rules/xcode/info_plist/xmake.lua
index 57d3c9995..bd991b6e1 100644
--- a/xmake/rules/xcode/info_plist/xmake.lua
+++ b/xmake/rules/xcode/info_plist/xmake.lua
@@ -32,7 +32,7 @@ rule("xcode.info_plist")
import("core.theme.theme")
import("core.project.depend")
import("core.tool.toolchain")
- import("private.utils.progress")
+ import("utils.progress")
-- check
assert(path.filename(sourcefile) == "Info.plist", "we only support Info.plist file!")
diff --git a/xmake/rules/xcode/metal/xmake.lua b/xmake/rules/xcode/metal/xmake.lua
new file mode 100644
index 000000000..a876f946b
--- /dev/null
+++ b/xmake/rules/xcode/metal/xmake.lua
@@ -0,0 +1,145 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- build metal files
+--
+-- @see https://developer.apple.com/documentation/metal/libraries/building_a_library_with_metal_s_command-line_tools
+--
+rule("xcode.metal")
+
+ -- support add_files("*.metal")
+ set_extensions(".metal")
+
+ on_load(function (target)
+ local cross
+ if target:is_plat("macosx") then
+ cross = "xcrun -sdk macosx "
+ elseif target:is_plat("iphoneos") then
+ cross = target:is_arch("i386", "x86_64") and "xcrun -sdk iphonesimulator " or "xcrun -sdk iphoneos "
+ elseif target:is_plat("watchos") then
+ cross = target:is_arch("i386") and "xcrun -sdk watchsimulator " or "xcrun -sdk watchos "
+ elseif target:is_plat("appletvos") then
+ cross = target:is_arch("i386", "x86_64") and "xcrun -sdk appletvsimulator " or "xcrun -sdk appletvos "
+ else
+ raise("unknown platform for xcode!")
+ end
+ target:data_set("xcode.metal.cross", cross)
+ end)
+
+ -- build *.metal to *.air
+ on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
+
+ -- get metal
+ import("core.tool.toolchain")
+ import("lib.detect.find_tool")
+ local cross = target:data("xcode.metal.cross")
+ local metal = assert(find_tool("metal", {program = cross .. " metal"}), "metal command not found!")
+
+ -- get xcode toolchain
+ local xcode = toolchain.load("xcode", {plat = target:plat(), arch = target:arch()})
+ local target_minver = xcode:config("target_minver")
+ local xcode_sysroot = xcode:config("xcode_sysroot")
+
+ -- init metal arguments
+ local objectfile = target:objectfile(sourcefile) .. ".air"
+ local argv = {"-c", "-ffast-math", "-gline-tables-only"}
+ if target_minver then
+ table.insert(argv, "-target")
+ local airarch = target:is_arch("x86_64", "arm64") and "air64" or "air32"
+ if target:is_plat("macosx") then
+ table.insert(argv, airarch .. "-apple-macos" .. target_minver)
+ elseif target:is_plat("iphoneos") then
+ local airtarget = airarch .. "-apple-ios" .. target_minver
+ if target:is_arch("x86_64", "i386") then
+ airtarget = airtarget .. "-simulator"
+ end
+ table.insert(argv, airtarget)
+ elseif target:is_plat("watchos") then
+ local airtarget = airarch .. "-apple-watchos" .. target_minver
+ if target:is_arch("x86_64", "i386") then
+ airtarget = airtarget .. "-simulator"
+ end
+ table.insert(argv, airtarget)
+ elseif target:is_plat("appletvos") then
+ local airtarget = airarch .. "-apple-tvos" .. target_minver
+ if target:is_arch("x86_64", "i386") then
+ airtarget = airtarget .. "-simulator"
+ end
+ table.insert(argv, airtarget)
+ end
+ end
+ if xcode_sysroot then
+ table.insert(argv, "-isysroot")
+ table.insert(argv, xcode_sysroot)
+ end
+ table.insert(argv, "-o")
+ table.insert(argv, objectfile)
+ table.insert(argv, sourcefile)
+
+ -- add commands
+ batchcmds:show_progress(opt.progress, "${color.build.object}compiling.metal %s", sourcefile)
+ batchcmds:mkdir(path.directory(objectfile))
+ batchcmds:vrunv(metal.program, argv)
+
+ -- add deps
+ batchcmds:add_depfiles(sourcefile)
+ batchcmds:set_depmtime(os.mtime(objectfile))
+ batchcmds:set_depcache(target:dependfile(objectfile))
+ end)
+
+ -- link *.air to *.metallib
+ before_linkcmd(function (target, batchcmds, opt)
+
+ -- get objectfiles
+ local objectfiles = {}
+ for rulename, sourcebatch in pairs(target:sourcebatches()) do
+ if rulename == "xcode.metal" then
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ table.insert(objectfiles, target:objectfile(sourcefile) .. ".air")
+ end
+ break
+ end
+ end
+ if #objectfiles == 0 then
+ return
+ end
+
+ -- get metallib
+ import("core.tool.toolchain")
+ import("lib.detect.find_tool")
+ local cross = target:data("xcode.metal.cross")
+ local metallib = assert(find_tool("metallib", {program = cross .. " metallib"}), "metallib command not found!")
+
+ -- get xcode toolchain
+ local xcode = toolchain.load("xcode", {plat = target:plat(), arch = target:arch()})
+ local xcode_sysroot = xcode:config("xcode_sysroot")
+
+ -- add commands
+ local resourcesdir = path.absolute(target:data("xcode.bundle.resourcesdir"))
+ local libraryfile = resourcesdir and path.join(resourcesdir, "default.metallib") or (target:targetfile() .. ".metallib")
+ batchcmds:show_progress(opt.progress, "${color.build.target}linking.metal %s", path.filename(libraryfile))
+ batchcmds:mkdir(path.directory(libraryfile))
+ batchcmds:vrunv(metallib.program, table.join({"-o", libraryfile}, objectfiles), {envs = {SDKROOT = xcode_sysroot}})
+
+ -- add deps
+ batchcmds:add_depfiles(objectfiles)
+ batchcmds:set_depmtime(os.mtime(libraryfile))
+ batchcmds:set_depcache(target:dependfile(libraryfile))
+ end)
diff --git a/xmake/rules/xcode/storyboard/xmake.lua b/xmake/rules/xcode/storyboard/xmake.lua
index 6ec23dd80..d96a1c002 100644
--- a/xmake/rules/xcode/storyboard/xmake.lua
+++ b/xmake/rules/xcode/storyboard/xmake.lua
@@ -32,7 +32,7 @@ rule("xcode.storyboard")
import("core.theme.theme")
import("core.project.depend")
import("core.tool.toolchain")
- import("private.utils.progress")
+ import("utils.progress")
-- get xcode sdk directory
local xcode_sdkdir = assert(get_config("xcode"), "xcode not found!")
diff --git a/xmake/rules/xcode/xcassets/xmake.lua b/xmake/rules/xcode/xcassets/xmake.lua
index 09185b226..9322d10c1 100644
--- a/xmake/rules/xcode/xcassets/xmake.lua
+++ b/xmake/rules/xcode/xcassets/xmake.lua
@@ -32,7 +32,7 @@ rule("xcode.xcassets")
import("core.theme.theme")
import("core.project.depend")
import("core.tool.toolchain")
- import("private.utils.progress")
+ import("utils.progress")
-- get xcode sdk directory
local xcode_sdkdir = assert(get_config("xcode"), "xcode not found!")
diff --git a/xmake/rules/xmake_cli/xmake.lua b/xmake/rules/xmake_cli/xmake.lua
index 2375c9e3b..a7e21a9e1 100644
--- a/xmake/rules/xmake_cli/xmake.lua
+++ b/xmake/rules/xmake_cli/xmake.lua
@@ -20,7 +20,7 @@
-- define rule: xmake cli program
rule("xmake.cli")
- before_load(function (target)
+ on_load(function (target)
target:set("kind", "binary")
assert(target:pkg("libxmake"), 'please add_packages("libxmake") to target(%s) first!', target:name())
end)
diff --git a/xmake/scripts/cmake_importfiles/xxxTargets.cmake b/xmake/scripts/cmake_importfiles/xxxTargets.cmake
index 7ade9f919..bdf2774e9 100644
--- a/xmake/scripts/cmake_importfiles/xxxTargets.cmake
+++ b/xmake/scripts/cmake_importfiles/xxxTargets.cmake
@@ -1,4 +1,4 @@
-# Generated by CMake
+# Generated by XMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
diff --git a/xmake/scripts/xrepo-hook.psm1 b/xmake/scripts/xrepo-hook.psm1
index 902ef3b16..2a2c24c05 100644
--- a/xmake/scripts/xrepo-hook.psm1
+++ b/xmake/scripts/xrepo-hook.psm1
@@ -10,25 +10,44 @@
#>
function Enter-XrepoEnvironment {
[CmdletBinding()]
- param();
+ param(
+ [string]$bnd
+ );
begin {
$script:xrepoOldEnvs = (Get-ChildItem -Path Env:);
- & $Env:XMAKE_EXE lua private.xrepo.action.env.info config;
- if (-not $?) {
- Exit 1;
- }
+ if ($bnd -eq $Null) {
+ & $Env:XMAKE_EXE lua private.xrepo.action.env.info config;
+ if (-not $?) {
+ Exit 1;
+ }
- $xmakeColorTermBackup, $Env:XMAKE_COLORTERM = $Env:XMAKE_COLORTERM, "nocolor";
- $xrepoPrompt = (& $Env:XMAKE_EXE lua private.xrepo.action.env.info prompt | Out-String);
- $Env:XMAKE_COLORTERM = $xmakeColorTermBackup;
- if (-not $xrepoPrompt.StartsWith("[")) {
- Write-Host $xrepoPrompt;
- Exit 1;
- }
+ $xmakeColorTermBackup, $Env:XMAKE_COLORTERM = $Env:XMAKE_COLORTERM, "nocolor";
+ $xrepoPrompt = (& $Env:XMAKE_EXE lua --quiet private.xrepo.action.env.info prompt | Out-String);
+ $Env:XMAKE_COLORTERM = $xmakeColorTermBackup;
+ if (-not $xrepoPrompt.StartsWith("[")) {
+ Write-Host "error: xmake.lua not found!";
+ Exit 1;
+ }
- $activateCommand = (& $Env:XMAKE_EXE lua private.xrepo.action.env.info script.powershell | Out-String);
+ $activateCommand = (& $Env:XMAKE_EXE lua --quiet private.xrepo.action.env.info script.powershell | Out-String);
+ } else {
+ & $Env:XMAKE_EXE lua private.xrepo.action.env.info config $bnd;
+ if (-not $?) {
+ Exit 1;
+ }
+
+ $xmakeColorTermBackup, $Env:XMAKE_COLORTERM = $Env:XMAKE_COLORTERM, "nocolor";
+ $xrepoPrompt = (& $Env:XMAKE_EXE lua --quiet private.xrepo.action.env.info prompt $bnd | Out-String);
+ $Env:XMAKE_COLORTERM = $xmakeColorTermBackup;
+ if (-not $xrepoPrompt.StartsWith("[")) {
+ Write-Host "error: invalid environment!";
+ Exit 1;
+ }
+
+ $activateCommand = (& $Env:XMAKE_EXE lua --quiet private.xrepo.action.env.info script.powershell $bnd | Out-String);
+ }
Write-Verbose "[xrepo env script.powershell]`n$activateCommand";
Invoke-Expression -Command $activateCommand;
diff --git a/xmake/templates/nim/console/project/src/main.nim b/xmake/templates/nim/console/project/src/main.nim
new file mode 100644
index 000000000..17179284f
--- /dev/null
+++ b/xmake/templates/nim/console/project/src/main.nim
@@ -0,0 +1 @@
+echo "hello xmake!"
diff --git a/xmake/templates/nim/console/project/xmake.lua b/xmake/templates/nim/console/project/xmake.lua
new file mode 100644
index 000000000..f41148c2f
--- /dev/null
+++ b/xmake/templates/nim/console/project/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.debug", "mode.release")
+
+target("${TARGETNAME}")
+ set_kind("binary")
+ add_files("src/main.nim")
+
+${FAQ}
diff --git a/xmake/templates/nim/console/template.lua b/xmake/templates/nim/console/template.lua
new file mode 100644
index 000000000..ed2e13b57
--- /dev/null
+++ b/xmake/templates/nim/console/template.lua
@@ -0,0 +1,2 @@
+template("console")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/nim/shared/project/src/foo.nim b/xmake/templates/nim/shared/project/src/foo.nim
new file mode 100644
index 000000000..cde4de7ca
--- /dev/null
+++ b/xmake/templates/nim/shared/project/src/foo.nim
@@ -0,0 +1,6 @@
+proc foo(n: int): int {.cdecl, exportc, dynlib.} =
+ if n < 2:
+ result = n
+ else:
+ result = foo(n - 1) + (n - 2).foo
+
diff --git a/xmake/templates/nim/shared/project/src/main.nim b/xmake/templates/nim/shared/project/src/main.nim
new file mode 100644
index 000000000..1be3abe69
--- /dev/null
+++ b/xmake/templates/nim/shared/project/src/main.nim
@@ -0,0 +1,3 @@
+proc foo(n: int): int {.cdecl, importc}
+
+echo foo(2)
diff --git a/xmake/templates/nim/shared/project/xmake.lua b/xmake/templates/nim/shared/project/xmake.lua
new file mode 100644
index 000000000..e2d380ac6
--- /dev/null
+++ b/xmake/templates/nim/shared/project/xmake.lua
@@ -0,0 +1,14 @@
+add_rules("mode.debug", "mode.release")
+
+target("${TARGETNAME}")
+ set_kind("shared")
+ add_files("src/foo.nim")
+
+target("${TARGETNAME}_demo")
+ set_kind("binary")
+ add_deps("${TARGETNAME}")
+ add_files("src/main.nim")
+
+${FAQ}
+
+
diff --git a/xmake/templates/nim/shared/template.lua b/xmake/templates/nim/shared/template.lua
new file mode 100644
index 000000000..d7ec5bae4
--- /dev/null
+++ b/xmake/templates/nim/shared/template.lua
@@ -0,0 +1,2 @@
+template("shared")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/nim/static/project/src/foo.nim b/xmake/templates/nim/static/project/src/foo.nim
new file mode 100644
index 000000000..be0904262
--- /dev/null
+++ b/xmake/templates/nim/static/project/src/foo.nim
@@ -0,0 +1,6 @@
+proc foo(n: int): int {.cdecl, exportc} =
+ if n < 2:
+ result = n
+ else:
+ result = foo(n - 1) + (n - 2).foo
+
diff --git a/xmake/templates/nim/static/project/src/main.nim b/xmake/templates/nim/static/project/src/main.nim
new file mode 100644
index 000000000..1be3abe69
--- /dev/null
+++ b/xmake/templates/nim/static/project/src/main.nim
@@ -0,0 +1,3 @@
+proc foo(n: int): int {.cdecl, importc}
+
+echo foo(2)
diff --git a/xmake/templates/nim/static/project/xmake.lua b/xmake/templates/nim/static/project/xmake.lua
new file mode 100644
index 000000000..cf70acb9e
--- /dev/null
+++ b/xmake/templates/nim/static/project/xmake.lua
@@ -0,0 +1,14 @@
+add_rules("mode.debug", "mode.release")
+
+target("${TARGETNAME}")
+ set_kind("static")
+ add_files("src/foo.nim")
+
+target("${TARGETNAME}_demo")
+ set_kind("binary")
+ add_deps("${TARGETNAME}")
+ add_files("src/main.nim")
+
+${FAQ}
+
+
diff --git a/xmake/templates/nim/static/template.lua b/xmake/templates/nim/static/template.lua
new file mode 100644
index 000000000..abfe91a4b
--- /dev/null
+++ b/xmake/templates/nim/static/template.lua
@@ -0,0 +1,2 @@
+template("static")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/pascal/console/project/src/main.pas b/xmake/templates/pascal/console/project/src/main.pas
new file mode 100644
index 000000000..a908ffab7
--- /dev/null
+++ b/xmake/templates/pascal/console/project/src/main.pas
@@ -0,0 +1,4 @@
+program Hello;
+begin
+ writeln ('Hello, world.');
+end.
diff --git a/xmake/templates/pascal/console/project/xmake.lua b/xmake/templates/pascal/console/project/xmake.lua
new file mode 100644
index 000000000..155005840
--- /dev/null
+++ b/xmake/templates/pascal/console/project/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.debug", "mode.release")
+
+target("${TARGETNAME}")
+ set_kind("binary")
+ add_files("src/*.pas")
+
+${FAQ}
diff --git a/xmake/templates/pascal/console/template.lua b/xmake/templates/pascal/console/template.lua
new file mode 100644
index 000000000..ed2e13b57
--- /dev/null
+++ b/xmake/templates/pascal/console/template.lua
@@ -0,0 +1,2 @@
+template("console")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/pascal/shared/project/src/foo.pas b/xmake/templates/pascal/shared/project/src/foo.pas
new file mode 100644
index 000000000..788950f46
--- /dev/null
+++ b/xmake/templates/pascal/shared/project/src/foo.pas
@@ -0,0 +1,19 @@
+library foo;
+
+{$mode objfpc}{$H+}
+
+function fib(n : Int64) : Int64; cdecl;
+begin
+ if n > 1 then
+ begin
+ Result := fib(n - 1) + fib(n - 2);
+ end
+ else
+ Result := 1;
+end;
+
+exports
+ fib;
+end.
+
+
diff --git a/xmake/templates/pascal/shared/project/src/main.pas b/xmake/templates/pascal/shared/project/src/main.pas
new file mode 100644
index 000000000..02d5e88d0
--- /dev/null
+++ b/xmake/templates/pascal/shared/project/src/main.pas
@@ -0,0 +1,13 @@
+program hello;
+
+function fib(n: Int64): Int64;
+ cdecl; external 'foo';
+
+var
+ Value: Integer;
+begin
+ Value := 5;
+ WriteLn(fib(Value));
+end.
+
+
diff --git a/xmake/templates/pascal/shared/project/xmake.lua b/xmake/templates/pascal/shared/project/xmake.lua
new file mode 100644
index 000000000..dd29cf486
--- /dev/null
+++ b/xmake/templates/pascal/shared/project/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+target("foo")
+ set_kind("shared")
+ add_files("src/foo.pas")
+
+target("${TARGETNAME}")
+ set_kind("binary")
+ add_deps("foo")
+ add_files("src/main.pas")
+
+
+${FAQ}
diff --git a/xmake/templates/pascal/shared/template.lua b/xmake/templates/pascal/shared/template.lua
new file mode 100644
index 000000000..d7ec5bae4
--- /dev/null
+++ b/xmake/templates/pascal/shared/template.lua
@@ -0,0 +1,2 @@
+template("shared")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/rust/console/project/src/main.rs b/xmake/templates/rust/console/project/src/main.rs
index fe3b8813c..88d5e2749 100644
--- a/xmake/templates/rust/console/project/src/main.rs
+++ b/xmake/templates/rust/console/project/src/main.rs
@@ -1,4 +1,3 @@
-fn main()
-{
+fn main() {
println!("hello xmake!");
}
diff --git a/xmake/templates/rust/console/project/xmake.lua b/xmake/templates/rust/console/project/xmake.lua
index 7a363c461..2d0e19145 100644
--- a/xmake/templates/rust/console/project/xmake.lua
+++ b/xmake/templates/rust/console/project/xmake.lua
@@ -1,13 +1,7 @@
--- add modes: debug and release
add_rules("mode.debug", "mode.release")
--- add target
target("${TARGETNAME}")
-
- -- set kind
set_kind("binary")
-
- -- add files
- add_files("src/*.rs")
+ add_files("src/main.rs")
${FAQ}
diff --git a/xmake/templates/rust/static/project/src/foo.rs b/xmake/templates/rust/static/project/src/foo.rs
new file mode 100644
index 000000000..a3a3aa4a6
--- /dev/null
+++ b/xmake/templates/rust/static/project/src/foo.rs
@@ -0,0 +1,4 @@
+pub fn add(a: i32, b: i32) -> i32 {
+ return a + b;
+}
+
diff --git a/xmake/templates/rust/static/project/src/interfaces.rs b/xmake/templates/rust/static/project/src/interfaces.rs
deleted file mode 100644
index 277008ba4..000000000
--- a/xmake/templates/rust/static/project/src/interfaces.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub fn add(a: i32, b: i32) -> i32
-{
- return a + b;
-}
-
diff --git a/xmake/templates/rust/static/project/src/main.rs b/xmake/templates/rust/static/project/src/main.rs
index 24049d150..205d23da3 100644
--- a/xmake/templates/rust/static/project/src/main.rs
+++ b/xmake/templates/rust/static/project/src/main.rs
@@ -1,7 +1,6 @@
-extern crate interfaces;
+extern crate foo;
-fn main()
-{
+fn main() {
println!("hello xmake!");
- println!("add: {}", interfaces::add(1, 1));
+ println!("add: {}", foo::add(1, 1));
}
diff --git a/xmake/templates/rust/static/project/xmake.lua b/xmake/templates/rust/static/project/xmake.lua
index a4761d2dc..79a9ac569 100644
--- a/xmake/templates/rust/static/project/xmake.lua
+++ b/xmake/templates/rust/static/project/xmake.lua
@@ -1,11 +1,10 @@
-target("interfaces")
+target("foo")
set_kind("static")
- add_files("src/interfaces.rs")
+ add_files("src/foo.rs")
target("${TARGETNAME}_demo")
set_kind("binary")
- add_deps("interfaces")
+ add_deps("foo")
add_files("src/main.rs")
- add_linkdirs("$(buildir)")
${FAQ}
diff --git a/xmake/templates/vala/console/project/src/main.vala b/xmake/templates/vala/console/project/src/main.vala
new file mode 100644
index 000000000..8e8a32da0
--- /dev/null
+++ b/xmake/templates/vala/console/project/src/main.vala
@@ -0,0 +1,21 @@
+using Lua;
+
+static int my_func (LuaVM vm) {
+ stdout.printf ("Vala Code From Lua Code! (%f)\n", vm.to_number (1));
+ return 1;
+}
+
+static int main (string[] args) {
+
+ string code = """
+ print "Lua Code From Vala Code!"
+ my_func(33)
+ """;
+
+ var vm = new LuaVM ();
+ vm.open_libs ();
+ vm.register ("my_func", my_func);
+ vm.do_string (code);
+
+ return 0;
+}
diff --git a/xmake/templates/vala/console/project/xmake.lua b/xmake/templates/vala/console/project/xmake.lua
new file mode 100644
index 000000000..474572597
--- /dev/null
+++ b/xmake/templates/vala/console/project/xmake.lua
@@ -0,0 +1,12 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("lua", "glib")
+
+target("${TARGETNAME}")
+ set_kind("binary")
+ add_rules("vala")
+ add_files("src/*.vala")
+ add_packages("lua", "glib")
+ add_values("vala.packages", "lua")
+
+${FAQ}
diff --git a/xmake/templates/vala/console/template.lua b/xmake/templates/vala/console/template.lua
new file mode 100644
index 000000000..ed2e13b57
--- /dev/null
+++ b/xmake/templates/vala/console/template.lua
@@ -0,0 +1,2 @@
+template("console")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/vala/shared/project/src/main.vala b/xmake/templates/vala/shared/project/src/main.vala
new file mode 100644
index 000000000..da9fd895e
--- /dev/null
+++ b/xmake/templates/vala/shared/project/src/main.vala
@@ -0,0 +1,6 @@
+using MyMath;
+
+public void main() {
+ stdout.printf("\n\t2 + 3 is %d", sum(2, 3));
+ stdout.printf("\n\t8 squared is %d\n", square(8));
+}
diff --git a/xmake/templates/vala/shared/project/src/mymath.vala b/xmake/templates/vala/shared/project/src/mymath.vala
new file mode 100644
index 000000000..4f4e761c5
--- /dev/null
+++ b/xmake/templates/vala/shared/project/src/mymath.vala
@@ -0,0 +1,9 @@
+namespace MyMath {
+ public int sum(int a, int b) {
+ return(a + b);
+ }
+
+ public int square(int a) {
+ return(a * a);
+ }
+}
diff --git a/xmake/templates/vala/shared/project/xmake.lua b/xmake/templates/vala/shared/project/xmake.lua
new file mode 100644
index 000000000..e9148106c
--- /dev/null
+++ b/xmake/templates/vala/shared/project/xmake.lua
@@ -0,0 +1,18 @@
+add_rules("mode.release", "mode.debug")
+
+add_requires("glib")
+
+target("mymath")
+ set_kind("shared")
+ add_rules("vala")
+ add_files("src/mymath.vala")
+ add_values("vala.header", "mymath.h")
+ add_values("vala.vapi", "mymath-1.0.vapi")
+ add_packages("glib")
+
+target("${TARGETNAME}")
+ set_kind("binary")
+ add_deps("mymath")
+ add_rules("vala")
+ add_files("src/main.vala")
+ add_packages("glib")
diff --git a/xmake/templates/vala/shared/template.lua b/xmake/templates/vala/shared/template.lua
new file mode 100644
index 000000000..d7ec5bae4
--- /dev/null
+++ b/xmake/templates/vala/shared/template.lua
@@ -0,0 +1,2 @@
+template("shared")
+ add_configfiles("xmake.lua")
diff --git a/xmake/templates/vala/static/project/src/main.vala b/xmake/templates/vala/static/project/src/main.vala
new file mode 100644
index 000000000..da9fd895e
--- /dev/null
+++ b/xmake/templates/vala/static/project/src/main.vala
@@ -0,0 +1,6 @@
+using MyMath;
+
+public void main() {
+ stdout.printf("\n\t2 + 3 is %d", sum(2, 3));
+ stdout.printf("\n\t8 squared is %d\n", square(8));
+}
diff --git a/xmake/templates/vala/static/project/src/mymath.vala b/xmake/templates/vala/static/project/src/mymath.vala
new file mode 100644
index 000000000..4f4e761c5
--- /dev/null
+++ b/xmake/templates/vala/static/project/src/mymath.vala
@@ -0,0 +1,9 @@
+namespace MyMath {
+ public int sum(int a, int b) {
+ return(a + b);
+ }
+
+ public int square(int a) {
+ return(a * a);
+ }
+}
diff --git a/xmake/templates/vala/static/project/xmake.lua b/xmake/templates/vala/static/project/xmake.lua
new file mode 100644
index 000000000..143566fcb
--- /dev/null
+++ b/xmake/templates/vala/static/project/xmake.lua
@@ -0,0 +1,18 @@
+add_rules("mode.release", "mode.debug")
+
+add_requires("glib")
+
+target("mymath")
+ set_kind("static")
+ add_rules("vala")
+ add_files("src/mymath.vala")
+ add_values("vala.header", "mymath.h")
+ add_values("vala.vapi", "mymath-1.0.vapi")
+ add_packages("glib")
+
+target("${TARGETNAME}")
+ set_kind("binary")
+ add_deps("mymath")
+ add_rules("vala")
+ add_files("src/main.vala")
+ add_packages("glib")
diff --git a/xmake/templates/vala/static/template.lua b/xmake/templates/vala/static/template.lua
new file mode 100644
index 000000000..abfe91a4b
--- /dev/null
+++ b/xmake/templates/vala/static/template.lua
@@ -0,0 +1,2 @@
+template("static")
+ add_configfiles("xmake.lua")
diff --git a/xmake/toolchains/armcc/xmake.lua b/xmake/toolchains/armcc/xmake.lua
new file mode 100644
index 000000000..f7c0fe837
--- /dev/null
+++ b/xmake/toolchains/armcc/xmake.lua
@@ -0,0 +1,53 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+toolchain("armcc")
+
+ set_homepage("https://www2.keil.com/mdk5/compiler/5")
+ set_description("ARM Compiler Version 5 of Keil MDK")
+
+ set_kind("cross")
+
+ set_toolset("cc", "armcc")
+ set_toolset("cxx", "armcc")
+ set_toolset("ld", "armlink")
+ set_toolset("ar", "armar")
+ set_toolset("as", "armasm")
+
+ on_check(function (toolchain)
+ import("lib.detect.find_tool")
+ import("detect.sdks.find_mdk")
+ local mdk = find_mdk()
+ if mdk and mdk.sdkdir_armcc and find_tool("armcc") then
+ toolchain:config_set("sdkdir", mdk.sdkdir_armcc)
+ toolchain:configs_save()
+ return true
+ end
+ end)
+
+
+ on_load(function (toolchain)
+ local arch = toolchain:arch()
+ if arch then
+ toolchain:add("cxflags", "--cpu " .. arch)
+ toolchain:add("asflags", "--cpu " .. arch)
+ toolchain:add("ldflags", "--cpu " .. arch)
+ end
+ end)
diff --git a/xmake/toolchains/armclang/xmake.lua b/xmake/toolchains/armclang/xmake.lua
new file mode 100644
index 000000000..dc8c1c696
--- /dev/null
+++ b/xmake/toolchains/armclang/xmake.lua
@@ -0,0 +1,66 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+toolchain("armclang")
+
+ set_homepage("https://www2.keil.com/mdk5/compiler/6")
+ set_description("ARM Compiler Version 6 of Keil MDK")
+
+ set_kind("cross")
+
+ set_toolset("cc", "armclang")
+ set_toolset("cxx", "armclang")
+ set_toolset("ld", "armlink")
+ set_toolset("ar", "armar")
+ set_toolset("as", "armclang")
+
+ on_check(function (toolchain)
+ import("lib.detect.find_tool")
+ import("detect.sdks.find_mdk")
+ local mdk = find_mdk()
+ if mdk and mdk.sdkdir_armclang and find_tool("armclang") then
+ toolchain:config_set("sdkdir", mdk.sdkdir_armclang)
+ toolchain:configs_save()
+ return true
+ end
+ end)
+
+ on_load(function (toolchain)
+ local arch = toolchain:arch()
+ if arch then
+ local arch_cpu = arch:lower()
+ local arch_cpu_ld = ""
+ local arch_target = ""
+ if arch_cpu:startswith("cortex-m") then
+ arch_cpu_ld = arch_cpu:replace("cortex-m", "Cortex-M", {plain = true})
+ arch_target = "arm-arm-none-eabi"
+ end
+ if arch_cpu:startswith("cortex-a") then
+ arch_cpu_ld = arch_cpu:replace("cortex-a", "Cortex-A", {plain = true})
+ arch_target = "aarch64-arm-none-eabi"
+ end
+ toolchain:add("cxflags", "-target=" .. arch_target)
+ toolchain:add("cxflags", "-mcpu=" .. arch_cpu)
+ toolchain:add("asflags", "-target=" .. arch_target)
+ toolchain:add("asflags", "-mcpu=" .. arch_cpu)
+ toolchain:add("ldflags", "--cpu " .. arch_cpu_ld)
+ end
+ end)
+
diff --git a/xmake/toolchains/circle/xmake.lua b/xmake/toolchains/circle/xmake.lua
new file mode 100644
index 000000000..9f0416e83
--- /dev/null
+++ b/xmake/toolchains/circle/xmake.lua
@@ -0,0 +1,51 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+toolchain("circle")
+
+ set_homepage("https://www.circle-lang.org/")
+ set_description("A new C++20 compiler. It's written from scratch and designed for easy extension.")
+
+ set_kind("standalone")
+
+ set_toolset("cc", "circle")
+ set_toolset("cxx", "circle")
+ set_toolset("ld", "circle")
+ set_toolset("sh", "circle")
+ set_toolset("ar", "ar")
+ set_toolset("strip", "strip")
+
+ on_check(function (toolchain)
+ return import("lib.detect.find_tool")("circle")
+ end)
+
+ on_load(function (toolchain)
+ local march
+ if toolchain:is_arch("x86_64", "x64") then
+ march = "-m64"
+ elseif toolchain:is_arch("i386", "x86") then
+ march = "-m32"
+ end
+ if march then
+ toolchain:add("cxflags", march)
+ toolchain:add("ldflags", march)
+ toolchain:add("shflags", march)
+ end
+ end)
diff --git a/xmake/toolchains/clang/xmake.lua b/xmake/toolchains/clang/xmake.lua
index cf184baf6..96d22eac7 100644
--- a/xmake/toolchains/clang/xmake.lua
+++ b/xmake/toolchains/clang/xmake.lua
@@ -18,37 +18,28 @@
-- @file xmake.lua
--
--- define toolchain
toolchain("clang")
- -- set homepage
set_homepage("https://clang.llvm.org/")
set_description("A C language family frontend for LLVM")
- -- mark as standalone toolchain
set_kind("standalone")
- -- set toolset
set_toolset("cc", "clang")
set_toolset("cxx", "clang", "clang++")
set_toolset("ld", "clang++", "clang")
set_toolset("sh", "clang++", "clang")
set_toolset("ar", "ar")
- set_toolset("ex", "ar")
set_toolset("strip", "strip")
set_toolset("mm", "clang")
set_toolset("mxx", "clang", "clang++")
set_toolset("as", "clang")
- -- check toolchain
on_check(function (toolchain)
return import("lib.detect.find_tool")("clang")
end)
- -- on load
on_load(function (toolchain)
-
- -- add march flags
local march
if toolchain:is_arch("x86_64", "x64") then
march = "-m64"
diff --git a/xmake/toolchains/cross/load.lua b/xmake/toolchains/cross/load.lua
index 04d6f3044..dc0fd1b12 100644
--- a/xmake/toolchains/cross/load.lua
+++ b/xmake/toolchains/cross/load.lua
@@ -42,7 +42,6 @@ function main(toolchain)
toolchain:add("toolset", "ld", cross .. "g++", cross .. "gcc", cross .. "clang++", cross .. "clang")
toolchain:add("toolset", "sh", cross .. "g++", cross .. "gcc", cross .. "clang++", cross .. "clang")
toolchain:add("toolset", "ar", cross .. "ar")
- toolchain:add("toolset", "ex", cross .. "ar")
toolchain:add("toolset", "ranlib", cross .. "ranlib")
toolchain:add("toolset", "strip", cross .. "strip")
diff --git a/xmake/toolchains/cuda/xmake.lua b/xmake/toolchains/cuda/xmake.lua
index ca25dcb74..29079d656 100644
--- a/xmake/toolchains/cuda/xmake.lua
+++ b/xmake/toolchains/cuda/xmake.lua
@@ -28,7 +28,7 @@ toolchain("cuda")
-- set toolset
set_toolset("cu", "nvcc", "clang")
set_toolset("culd", "nvcc")
- set_toolset("cu-ccbin", "$(env CXX)", "$(env CC)", "clang", "gcc")
+ set_toolset("cu-ccbin", "$(env CXX)", "$(env CC)")
-- bind msvc environments, because nvcc will call cl.exe
on_load(function (toolchain)
diff --git a/xmake/toolchains/emcc/xmake.lua b/xmake/toolchains/emcc/xmake.lua
index 2623fdf24..1379bd1c2 100644
--- a/xmake/toolchains/emcc/xmake.lua
+++ b/xmake/toolchains/emcc/xmake.lua
@@ -37,7 +37,6 @@ toolchain("emcc")
set_toolset("ld", "em++" .. suffix, "emcc" .. suffix)
set_toolset("sh", "em++" .. suffix, "emcc" .. suffix)
set_toolset("ar", "emar" .. suffix)
- set_toolset("ex", "emar" .. suffix)
set_toolset("as", "emcc" .. suffix)
-- check toolchain
diff --git a/xmake/toolchains/envs/xmake.lua b/xmake/toolchains/envs/xmake.lua
index 500eb38c6..b40cf6166 100644
--- a/xmake/toolchains/envs/xmake.lua
+++ b/xmake/toolchains/envs/xmake.lua
@@ -30,7 +30,6 @@ toolchain("envs")
set_toolset("ld", "$(env LD)", "$(env CXX)")
set_toolset("sh", "$(env SH)", "$(env LD)", "$(env CXX)")
set_toolset("ar", "$(env AR)")
- set_toolset("ex", "$(env EX)", "$(env AR)")
set_toolset("strip", "$(env STRIP)")
set_toolset("ranlib","$(env RANLIB)")
set_toolset("mm", "$(env MM)")
diff --git a/xmake/toolchains/fpc/xmake.lua b/xmake/toolchains/fpc/xmake.lua
new file mode 100644
index 000000000..13231db7b
--- /dev/null
+++ b/xmake/toolchains/fpc/xmake.lua
@@ -0,0 +1,42 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- define toolchain
+toolchain("fpc")
+
+ -- set homepage
+ set_homepage("https://www.freepascal.org/")
+ set_description("Free Pascal Programming Language Compiler")
+
+ -- set toolset
+ set_toolset("pc", "$(env PC)", "fpc")
+ set_toolset("pcld", "$(env PC)", "fpc")
+ set_toolset("pcsh", "$(env PC)", "fpc")
+
+ -- on load
+ on_load(function (toolchain)
+ if toolchain:is_plat("linux") then
+ toolchain:set("pcldflags", "-k-lc")
+ toolchain:set("pcshflags", "-k-lc")
+ else
+ toolchain:set("pcldflags", "")
+ toolchain:set("pcshflags", "")
+ end
+ end)
diff --git a/xmake/toolchains/gcc-10/xmake.lua b/xmake/toolchains/gcc-10/xmake.lua
new file mode 100644
index 000000000..b1e2c8883
--- /dev/null
+++ b/xmake/toolchains/gcc-10/xmake.lua
@@ -0,0 +1,3 @@
+includes(path.join(os.scriptdir(), "../gcc/xmake.lua"))
+
+toolchain_gcc("10")
diff --git a/xmake/toolchains/gcc-11/xmake.lua b/xmake/toolchains/gcc-11/xmake.lua
new file mode 100644
index 000000000..2714c7718
--- /dev/null
+++ b/xmake/toolchains/gcc-11/xmake.lua
@@ -0,0 +1,3 @@
+includes(path.join(os.scriptdir(), "../gcc/xmake.lua"))
+
+toolchain_gcc("11")
diff --git a/xmake/toolchains/gcc-8/xmake.lua b/xmake/toolchains/gcc-8/xmake.lua
new file mode 100644
index 000000000..716477e01
--- /dev/null
+++ b/xmake/toolchains/gcc-8/xmake.lua
@@ -0,0 +1,3 @@
+includes(path.join(os.scriptdir(), "../gcc/xmake.lua"))
+
+toolchain_gcc("8")
diff --git a/xmake/toolchains/gcc-9/xmake.lua b/xmake/toolchains/gcc-9/xmake.lua
new file mode 100644
index 000000000..d33f396f6
--- /dev/null
+++ b/xmake/toolchains/gcc-9/xmake.lua
@@ -0,0 +1,3 @@
+includes(path.join(os.scriptdir(), "../gcc/xmake.lua"))
+
+toolchain_gcc("9")
diff --git a/xmake/toolchains/gcc/xmake.lua b/xmake/toolchains/gcc/xmake.lua
index 54816a98e..365341eda 100644
--- a/xmake/toolchains/gcc/xmake.lua
+++ b/xmake/toolchains/gcc/xmake.lua
@@ -19,33 +19,35 @@
--
-- define toolchain
-toolchain("gcc")
+function toolchain_gcc(version)
+local suffix = ""
+if version then
+ suffix = suffix .. "-" .. version
+end
+toolchain("gcc" .. suffix)
-- set homepage
set_homepage("https://gcc.gnu.org/")
- set_description("GNU Compiler Collection")
+ set_description("GNU Compiler Collection" .. (version and (" (" .. version .. ")") or ""))
-- mark as standalone toolchain
set_kind("standalone")
-- set toolset
- set_toolset("cc", "gcc")
- set_toolset("cxx", "gcc", "g++")
- set_toolset("ld", "g++", "gcc")
- set_toolset("sh", "g++", "gcc")
+ set_toolset("cc", "gcc" .. suffix)
+ set_toolset("cxx", "gcc" .. suffix, "g++" .. suffix)
+ set_toolset("ld", "g++" .. suffix, "gcc" .. suffix)
+ set_toolset("sh", "g++" .. suffix, "gcc" .. suffix)
set_toolset("ar", "ar")
- set_toolset("ex", "ar")
set_toolset("strip", "strip")
- set_toolset("mm", "gcc")
- set_toolset("mxx", "gcc", "g++")
- set_toolset("as", "gcc")
+ set_toolset("mm", "gcc" .. suffix)
+ set_toolset("mxx", "gcc" .. suffix, "g++" .. suffix)
+ set_toolset("as", "gcc" .. suffix)
- -- check toolchain
on_check(function (toolchain)
- return import("lib.detect.find_tool")("gcc")
+ return import("lib.detect.find_tool")("gcc" .. suffix)
end)
- -- on load
on_load(function (toolchain)
-- add march flags
@@ -63,3 +65,5 @@ toolchain("gcc")
toolchain:add("shflags", march)
end
end)
+end
+toolchain_gcc()
diff --git a/xmake/toolchains/icc/check.lua b/xmake/toolchains/icc/check.lua
index 3b9c7b953..9dde538f0 100644
--- a/xmake/toolchains/icc/check.lua
+++ b/xmake/toolchains/icc/check.lua
@@ -28,7 +28,8 @@ import("lib.detect.find_tool")
function _check_intel_on_windows(toolchain)
-- have been checked?
- if config.get("__iclvarsall") then
+ local varsall = toolchain:config("varsall")
+ if varsall then
return true
end
@@ -38,18 +39,11 @@ function _check_intel_on_windows(toolchain)
local iclvarsall = iccenv.iclvars
local iclenv = iclvarsall[toolchain:arch()]
if iclenv and iclenv.PATH and iclenv.INCLUDE and iclenv.LIB then
-
- -- save iclvars
- config.set("__iclvarsall", iclvarsall)
-
- -- check compiler
- local program = nil
local tool = find_tool("icl.exe", {force = true, envs = iclenv, version = true})
if tool then
- program = tool.program
- end
- if program then
cprint("checking for Intel C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain:config_set("varsall", iclvarsall)
+ toolchain:configs_save()
return true
end
end
@@ -58,7 +52,23 @@ end
-- check intel on linux
function _check_intel_on_linux(toolchain)
- return find_tool("icc")
+ local iccenv = toolchain:config("iccenv")
+ if iccenv then
+ return true
+ end
+ iccenv = find_iccenv()
+ if iccenv then
+ local ldname = is_host("macosx") and "DYLD_LIBRARY_PATH" or "LD_LIBRARY_PATH"
+ local tool = find_tool("icc", {force = true, envs = {[ldname] = iccenv.libdir}, paths = iccenv.bindir})
+ if tool then
+ cprint("checking for Intel C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain:config_set("iccenv", iccenv)
+ toolchain:config_set("bindir", iccenv.bindir)
+ toolchain:configs_save()
+ return true
+ end
+ return true
+ end
end
-- main entry
diff --git a/xmake/toolchains/icc/load.lua b/xmake/toolchains/icc/load.lua
index e4cee9959..e1ceba260 100644
--- a/xmake/toolchains/icc/load.lua
+++ b/xmake/toolchains/icc/load.lua
@@ -26,7 +26,7 @@ import("core.project.config")
function _add_iclenv(toolchain, name)
-- get iclvarsall
- local iclvarsall = config.get("__iclvarsall")
+ local iclvarsall = toolchain:config("varsall")
if not iclvarsall then
return
end
@@ -58,14 +58,12 @@ function _load_intel_on_windows(toolchain)
toolchain:set("toolset", "ld", "link.exe")
toolchain:set("toolset", "sh", "link.exe")
toolchain:set("toolset", "ar", "link.exe")
- toolchain:set("toolset", "ex", "lib.exe")
else
toolchain:set("toolset", "cc", "icc")
toolchain:set("toolset", "cxx", "icpc", "icc")
toolchain:set("toolset", "ld", "icpc", "icc")
toolchain:set("toolset", "sh", "icpc", "icc")
toolchain:set("toolset", "ar", "ar")
- toolchain:set("toolset", "ex", "ar")
toolchain:set("toolset", "strip", "strip")
toolchain:set("toolset", "as", "icc")
end
@@ -86,7 +84,6 @@ function _load_intel_on_linux(toolchain)
toolchain:set("toolset", "ld", "icpc", "icc")
toolchain:set("toolset", "sh", "icpc", "icc")
toolchain:set("toolset", "ar", "ar")
- toolchain:set("toolset", "ex", "ar")
toolchain:set("toolset", "strip", "strip")
toolchain:set("toolset", "as", "icc")
@@ -103,6 +100,13 @@ function _load_intel_on_linux(toolchain)
toolchain:add("ldflags", march)
toolchain:add("shflags", march)
end
+
+ -- get icc environments
+ local iccenv = toolchain:config("iccenv")
+ if iccenv then
+ local ldname = is_host("macosx") and "DYLD_LIBRARY_PATH" or "LD_LIBRARY_PATH"
+ toolchain:add("runenvs", ldname, iccenv.libdir)
+ end
end
-- main entry
diff --git a/xmake/toolchains/ifort/check.lua b/xmake/toolchains/ifort/check.lua
index 67d4e3931..285f5c86c 100644
--- a/xmake/toolchains/ifort/check.lua
+++ b/xmake/toolchains/ifort/check.lua
@@ -28,7 +28,8 @@ import("lib.detect.find_tool")
function _check_intel_on_windows(toolchain)
-- have been checked?
- if config.get("__ifortvarsall") then
+ local varsall = toolchain:config("varsall")
+ if varsall then
return true
end
@@ -38,18 +39,11 @@ function _check_intel_on_windows(toolchain)
local ifortvarsall = ifortenv.ifortvars
local ifortenv = ifortvarsall[toolchain:arch()]
if ifortenv and ifortenv.PATH and ifortenv.INCLUDE and ifortenv.LIB then
-
- -- save ifortvars
- config.set("__ifortvarsall", ifortvarsall)
-
- -- check compiler
- local program = nil
local tool = find_tool("ifort.exe", {force = true, envs = ifortenv, version = true})
if tool then
- program = tool.program
- end
- if program then
cprint("checking for Intel Fortran Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain:config_set("varsall", ifortvarsall)
+ toolchain:configs_save()
return true
end
end
@@ -58,7 +52,23 @@ end
-- check intel on linux
function _check_intel_on_linux(toolchain)
- return find_tool("ifort")
+ local ifortenv = toolchain:config("ifortenv")
+ if ifortenv then
+ return true
+ end
+ ifortenv = find_ifortenv()
+ if ifortenv then
+ local ldname = is_host("macosx") and "DYLD_LIBRARY_PATH" or "LD_LIBRARY_PATH"
+ local tool = find_tool("ifort", {force = true, envs = {[ldname] = ifortenv.libdir}, paths = ifortenv.bindir})
+ if tool then
+ cprint("checking for Intel Fortran Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain:config_set("ifortenv", ifortenv)
+ toolchain:config_set("bindir", ifortenv.bindir)
+ toolchain:configs_save()
+ return true
+ end
+ return true
+ end
end
-- main entry
diff --git a/xmake/toolchains/ifort/load.lua b/xmake/toolchains/ifort/load.lua
index 8fa00c6ec..2cb212a57 100644
--- a/xmake/toolchains/ifort/load.lua
+++ b/xmake/toolchains/ifort/load.lua
@@ -26,7 +26,7 @@ import("core.project.config")
function _add_ifortenv(toolchain, name)
-- get ifortvarsall
- local ifortvarsall = config.get("__ifortvarsall")
+ local ifortvarsall = toolchain:config("varsall")
if not ifortvarsall then
return
end
@@ -56,7 +56,6 @@ function _load_intel_on_windows(toolchain)
toolchain:set("toolset", "fcld", "ifort.exe")
toolchain:set("toolset", "fcsh", "ifort.exe")
toolchain:set("toolset", "ar", "link.exe")
- toolchain:set("toolset", "ex", "lib.exe")
-- add ifort environments
_add_ifortenv(toolchain, "PATH")
@@ -86,6 +85,13 @@ function _load_intel_on_linux(toolchain)
toolchain:add("fcldflags", march)
toolchain:add("fcshflags", march)
end
+
+ -- get ifort environments
+ local ifortenv = toolchain:config("ifortenv")
+ if ifortenv then
+ local ldname = is_host("macosx") and "DYLD_LIBRARY_PATH" or "LD_LIBRARY_PATH"
+ toolchain:add("runenvs", ldname, ifortenv.libdir)
+ end
end
-- main entry
diff --git a/xmake/toolchains/llvm/xmake.lua b/xmake/toolchains/llvm/xmake.lua
index e08cb0e5d..40ec8fa92 100644
--- a/xmake/toolchains/llvm/xmake.lua
+++ b/xmake/toolchains/llvm/xmake.lua
@@ -36,7 +36,6 @@ toolchain("llvm")
set_toolset("ld", "clang++", "clang")
set_toolset("sh", "clang++", "clang")
set_toolset("ar", "llvm-ar")
- set_toolset("ex", "llvm-ar")
set_toolset("ranlib", "llvm-ranlib")
set_toolset("strip", "llvm-strip")
diff --git a/xmake/toolchains/mingw/xmake.lua b/xmake/toolchains/mingw/xmake.lua
index 3ddd5c103..188b5ae8a 100644
--- a/xmake/toolchains/mingw/xmake.lua
+++ b/xmake/toolchains/mingw/xmake.lua
@@ -61,7 +61,6 @@ toolchain("mingw")
if is_host("windows") and bindir then
-- @note we uses bin/ar.exe instead of bin/cross-gcc-ar.exe, @see https://github.com/xmake-io/xmake/issues/807#issuecomment-635779210
toolchain:add("toolset", "ar", path.join(bindir, "ar"))
- toolchain:add("toolset", "ex", path.join(bindir, "ar"))
toolchain:add("toolset", "strip", path.join(bindir, "strip"))
toolchain:add("toolset", "ranlib", path.join(bindir, "ranlib"))
end
@@ -72,7 +71,6 @@ toolchain("mingw")
toolchain:add("toolset", "ld", cross .. "g++", cross .. "gcc")
toolchain:add("toolset", "sh", cross .. "g++", cross .. "gcc")
toolchain:add("toolset", "ar", cross .. "ar")
- toolchain:add("toolset", "ex", cross .. "ar")
toolchain:add("toolset", "strip", cross .. "strip")
toolchain:add("toolset", "ranlib", cross .. "ranlib")
toolchain:add("toolset", "mrc", cross .. "windres")
diff --git a/xmake/toolchains/msvc/check.lua b/xmake/toolchains/msvc/check.lua
index 634249232..ce3fdd8d9 100644
--- a/xmake/toolchains/msvc/check.lua
+++ b/xmake/toolchains/msvc/check.lua
@@ -60,6 +60,8 @@ function _check_vsenv(toolchain)
-- save vcvars
toolchain:config_set("vcvars", vcvars)
+ toolchain:config_set("vs_toolset", vcvars.VCToolsVersion)
+ toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion)
-- check compiler
local program = nil
diff --git a/xmake/toolchains/msvc/load.lua b/xmake/toolchains/msvc/load.lua
index bb7e2de3d..ee61b46ab 100644
--- a/xmake/toolchains/msvc/load.lua
+++ b/xmake/toolchains/msvc/load.lua
@@ -54,18 +54,19 @@ function main(toolchain)
toolchain:set("toolset", "ld", "link.exe")
toolchain:set("toolset", "sh", "link.exe")
toolchain:set("toolset", "ar", "link.exe")
- toolchain:set("toolset", "ex", "lib.exe")
-- add vs environments
- _add_vsenv(toolchain, "PATH")
- _add_vsenv(toolchain, "LIB")
- _add_vsenv(toolchain, "INCLUDE")
- _add_vsenv(toolchain, "LIBPATH")
- -- find_rc.lua need them
- _add_vsenv(toolchain, "WindowsSdkDir")
- _add_vsenv(toolchain, "WindowsSDKVersion")
+ local expect_vars = {"PATH", "LIB", "INCLUDE", "LIBPATH"}
+ for _, name in ipairs(expect_vars) do
+ _add_vsenv(toolchain, name)
+ end
+ for _, name in ipairs(find_vstudio.get_vcvars()) do
+ if not table.contains(expect_vars, name:upper()) then
+ _add_vsenv(toolchain, name)
+ end
+ end
-- add some default flags
- toolchain:add("cxxflags", "/EHsc")
+ toolchain:add("cl.cxxflags", "/EHsc")
end
diff --git a/xmake/toolchains/ndk/check.lua b/xmake/toolchains/ndk/check.lua
index aaf1d609a..991e4e3d9 100644
--- a/xmake/toolchains/ndk/check.lua
+++ b/xmake/toolchains/ndk/check.lua
@@ -49,6 +49,7 @@ function _check_ndk(toolchain)
toolchain:config_set("ndk", ndk.sdkdir)
toolchain:config_set("bindir", ndk.bindir)
toolchain:config_set("cross", ndk.cross)
+ toolchain:config_set("llvm_toolchain", ndk.llvm_toolchain)
toolchain:config_set("gcc_toolchain", ndk.gcc_toolchain)
toolchain:config_set("ndkver", ndk.ndkver)
toolchain:config_set("ndk_sdkver", ndk.sdkver)
diff --git a/xmake/toolchains/ndk/load.lua b/xmake/toolchains/ndk/load.lua
index 29e88d7ad..494558673 100644
--- a/xmake/toolchains/ndk/load.lua
+++ b/xmake/toolchains/ndk/load.lua
@@ -89,7 +89,6 @@ function main(toolchain)
toolchain:set("toolset", "ld", "clang++", "clang", cross .. "g++", cross .. "gcc")
toolchain:set("toolset", "sh", "clang++", "clang", cross .. "g++", cross .. "gcc")
toolchain:set("toolset", "ar", gcc_toolchain_bin and path.join(gcc_toolchain_bin, cross .. "ar") or (cross .. "ar"), "llvm-ar")
- toolchain:set("toolset", "ex", gcc_toolchain_bin and path.join(gcc_toolchain_bin, cross .. "ar") or (cross .. "ar"), "llvm-ar")
toolchain:set("toolset", "ranlib", gcc_toolchain_bin and path.join(gcc_toolchain_bin, cross .. "ranlib") or (cross .. "ranlib"))
toolchain:set("toolset", "strip", gcc_toolchain_bin and path.join(gcc_toolchain_bin, cross .. "strip") or (cross .. "strip"))
@@ -167,8 +166,10 @@ function main(toolchain)
local ndk_sysroot = toolchain:config("ndk_sysroot")
if ndk_sysroot and os.isdir(ndk_sysroot) then
local triple = _get_triple(arch)
- toolchain:add("cxflags", "-D__ANDROID_API__=" .. ndk_sdkver)
- toolchain:add("asflags", "-D__ANDROID_API__=" .. ndk_sdkver)
+ if ndkver and tonumber(ndkver) < 22 then
+ toolchain:add("cxflags", "-D__ANDROID_API__=" .. ndk_sdkver)
+ toolchain:add("asflags", "-D__ANDROID_API__=" .. ndk_sdkver)
+ end
toolchain:add("cflags", "--sysroot=" .. ndk_sysroot)
toolchain:add("cxxflags","--sysroot=" .. ndk_sysroot)
toolchain:add("asflags", "--sysroot=" .. ndk_sysroot)
diff --git a/xmake/toolchains/nim/xmake.lua b/xmake/toolchains/nim/xmake.lua
new file mode 100644
index 000000000..e85a80204
--- /dev/null
+++ b/xmake/toolchains/nim/xmake.lua
@@ -0,0 +1,41 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+toolchain("nim")
+
+ set_homepage("https://nim-lang.org/")
+ set_description("Nim Programming Language Compiler")
+
+ set_toolset("nc", "$(env NC)", "nim")
+ set_toolset("ncld", "$(env NC)", "nim")
+ set_toolset("ncsh", "$(env NC)", "nim")
+ set_toolset("ncar", "$(env NC)", "nim")
+
+ on_load(function (toolchain)
+ if toolchain:is_plat("windows") then
+ toolchain:set("ncflags", "--cc:vcc")
+ local msvc = import("core.tool.toolchain", {anonymous = true}).load("msvc", {plat = toolchain:plat(), arch = toolchain:arch()})
+ for name, value in pairs(msvc:get("runenvs")) do
+ toolchain:add("runenvs", name, value)
+ end
+ end
+ toolchain:set("ncshflags", "")
+ toolchain:set("ncldflags", "")
+ end)
diff --git a/xmake/toolchains/sdcc/xmake.lua b/xmake/toolchains/sdcc/xmake.lua
index 869135578..18dc595ff 100644
--- a/xmake/toolchains/sdcc/xmake.lua
+++ b/xmake/toolchains/sdcc/xmake.lua
@@ -36,7 +36,6 @@ toolchain("sdcc")
set_toolset("ld", "sdcc")
set_toolset("sh", "sdcc")
set_toolset("ar", "sdar")
- set_toolset("ex", "sdar")
-- set archs
set_archs("stm8", "mcs51", "z80", "z180", "r2k", "r3ka", "s08", "hc08")
@@ -52,8 +51,6 @@ toolchain("sdcc")
-- on load
on_load(function (toolchain)
-
- -- add port flags for arch
local arch = toolchain:arch()
if arch then
toolchain:add("cxflags", "-m" .. arch)
diff --git a/xmake/toolchains/wasi/xmake.lua b/xmake/toolchains/wasi/xmake.lua
new file mode 100644
index 000000000..9d6ec360c
--- /dev/null
+++ b/xmake/toolchains/wasi/xmake.lua
@@ -0,0 +1,62 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author wsw0108
+-- @file xmake.lua
+--
+
+-- define toolchain
+toolchain("wasi")
+
+ -- set homepage
+ set_homepage("https://github.com/WebAssembly/wasi-sdk")
+ set_description("WASI-enabled WebAssembly C/C++ toolchain.")
+
+ -- mark as standalone toolchain
+ set_kind("standalone")
+
+ -- set toolset
+ set_toolset("cc", "clang")
+ set_toolset("cxx", "clang", "clang++")
+ set_toolset("cpp", "clang -E")
+ set_toolset("as", "clang")
+ set_toolset("ld", "clang++", "clang")
+ set_toolset("sh", "clang++", "clang")
+ set_toolset("ar", "llvm-ar")
+ set_toolset("ranlib", "llvm-ranlib")
+ set_toolset("strip", "llvm-strip")
+
+ -- check toolchain
+ on_check(function (toolchain)
+ return import("lib.detect.find_tool")("clang")
+ end)
+
+ -- on load
+ on_load(function (toolchain)
+
+ local sdkdir = toolchain:sdkdir()
+ local sysroot = path.join(sdkdir, "share", "wasi-sysroot")
+ toolchain:add("cxflags", "--sysroot=" .. sysroot)
+ toolchain:add("mxflags", "--sysroot=" .. sysroot)
+ toolchain:add("ldflags", "--sysroot=" .. sysroot)
+ toolchain:add("shflags", "--sysroot=" .. sysroot)
+
+ -- add bin search library for loading some dependent .dll files windows
+ local bindir = toolchain:bindir()
+ if bindir and is_host("windows") then
+ toolchain:add("runenvs", "PATH", bindir)
+ end
+ end)
diff --git a/xmake/toolchains/xcode/xmake.lua b/xmake/toolchains/xcode/xmake.lua
index b4d8c3d66..f2b2683ff 100644
--- a/xmake/toolchains/xcode/xmake.lua
+++ b/xmake/toolchains/xcode/xmake.lua
@@ -60,7 +60,6 @@ toolchain("xcode")
toolchain:set("toolset", "ld", cross .. "clang++", cross .. "clang")
toolchain:set("toolset", "sh", cross .. "clang++", cross .. "clang")
toolchain:set("toolset", "ar", cross .. "ar")
- toolchain:set("toolset", "ex", cross .. "ar")
toolchain:set("toolset", "strip", cross .. "strip")
toolchain:set("toolset", "dsymutil", cross .. "dsymutil", "dsymutil")
toolchain:set("toolset", "mm", cross .. "clang")