mirror of
https://github.com/lkl/linux.git
synced 2025-12-20 00:23:14 +09:00
lkl tools: improve the build system
Improve the auto configuration process by moving it to a separate makefile and by generating both makefile and C header auto configuration. For clarity, it also adds a Targets file to describe what the targets are and what link flags to use instead of doing it in the main makefile. Also, build the tests with the main targets instead of having to issue "make tests" to both build and run the tests. This change is needed since we will switch to a different test runner. Signed-off-by: Octavian Purdila <tavi@cs.pub.ro>
This commit is contained in:
3
tools/lkl/.gitignore
vendored
3
tools/lkl/.gitignore
vendored
@@ -8,3 +8,6 @@ tests/valgrind*.xml
|
|||||||
*.dll
|
*.dll
|
||||||
tests/net-test
|
tests/net-test
|
||||||
tests/disk
|
tests/disk
|
||||||
|
Makefile.conf
|
||||||
|
include/autoconf.h
|
||||||
|
tests/autoconf.sh
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
CFLAGS_lklfuse.o += -D_FILE_OFFSET_BITS=64
|
CFLAGS_lklfuse.o += -D_FILE_OFFSET_BITS=64
|
||||||
|
|
||||||
cptofs-y += cptofs.o
|
cptofs-$(LKL_HOST_CONFIG_ARCHIVE) += cptofs.o
|
||||||
fs2tar-y += fs2tar.o
|
fs2tar-$(LKL_HOST_CONFIG_ARCHIVE) += fs2tar.o
|
||||||
lklfuse-y += lklfuse.o
|
lklfuse-$(LKL_HOST_CONFIG_FUSE) += lklfuse.o
|
||||||
|
|
||||||
|
|||||||
@@ -4,88 +4,11 @@
|
|||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
MAKEFLAGS += -r --no-print-directory
|
MAKEFLAGS += -r --no-print-directory
|
||||||
|
|
||||||
ifeq ($(V),1)
|
ifneq ($(silent),1)
|
||||||
Q =
|
ifneq ($(V),1)
|
||||||
else
|
QUIET_AUTOCONF = @echo ' AUTOCONF '$@;
|
||||||
Q = @
|
Q = @
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# default target
|
|
||||||
all:
|
|
||||||
|
|
||||||
-include ../scripts/Makefile.include
|
|
||||||
|
|
||||||
# By default we want to use gcc (as does Linux), especially as the clang
|
|
||||||
# cross toolchain does not use prefixed names
|
|
||||||
CC := $(CROSS_COMPILE)gcc
|
|
||||||
LD := $(CROSS_COMPILE)$(LD)
|
|
||||||
AR := $(CROSS_COMPILE)$(AR)
|
|
||||||
export CC LD AR
|
|
||||||
|
|
||||||
EXESUF :=
|
|
||||||
SOSUF := .so
|
|
||||||
|
|
||||||
PREFIX := /usr
|
|
||||||
|
|
||||||
ifeq (,$(srctree))
|
|
||||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
|
||||||
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
|
||||||
endif
|
|
||||||
export srctree
|
|
||||||
|
|
||||||
|
|
||||||
# Target build configuration
|
|
||||||
|
|
||||||
export CFLAGS += -I$(OUTPUT)/include -Iinclude -Wall -g -O2 -Wextra \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-Wno-missing-field-initializers -fno-strict-aliasing
|
|
||||||
LDFLAGS += -pie
|
|
||||||
|
|
||||||
OUTPUT_FORMAT = $(shell $(LD) -r -print-output-format)
|
|
||||||
|
|
||||||
ifneq (,$(filter $(OUTPUT_FORMAT),elf64-x86-64 elf32-i386 elf64-x86-64-freebsd elf32-littlearm elf64-littleaarch64))
|
|
||||||
OUTPUT_DEF = $(shell echo | $(CC) -dM -E -)
|
|
||||||
CFLAGS += -fPIC -pthread
|
|
||||||
ifeq (,$(filter $(OUTPUT_DEF),__ANDROID__))
|
|
||||||
LDLIBS += -lrt -lpthread
|
|
||||||
endif
|
|
||||||
export CONFIG_AUTO_LKL_POSIX_HOST=y
|
|
||||||
CFLAGS += -DCONFIG_AUTO_LKL_POSIX_HOST
|
|
||||||
|
|
||||||
# Intel DPDK configuration
|
|
||||||
ifeq ($(dpdk),yes)
|
|
||||||
export CONFIG_AUTO_LKL_VIRTIO_NET_DPDK=y
|
|
||||||
RTE_SDK ?= $(shell pwd)/dpdk-17.02
|
|
||||||
RTE_TARGET ?= build
|
|
||||||
DPDK_LIBS = -lrte_pmd_vmxnet3_uio -lrte_pmd_ixgbe -lrte_pmd_e1000
|
|
||||||
DPDK_LIBS += -lrte_pmd_virtio
|
|
||||||
DPDK_LIBS += -lrte_timer -lrte_hash -lrte_mbuf -lrte_ethdev -lrte_eal
|
|
||||||
DPDK_LIBS += -lrte_mempool -lrte_ring -lrte_pmd_ring
|
|
||||||
DPDK_LIBS += -lrte_kvargs -lrte_net
|
|
||||||
CFLAGS += -I$(RTE_SDK)/$(RTE_TARGET)/include -msse4.2 -mpopcnt
|
|
||||||
CFLAGS += -DCONFIG_AUTO_LKL_VIRTIO_NET_DPDK
|
|
||||||
LDFLAGS +=-L$(RTE_SDK)/$(RTE_TARGET)/lib
|
|
||||||
LDFLAGS +=-Wl,--whole-archive $(DPDK_LIBS) -Wl,--no-whole-archive -lm -ldl
|
|
||||||
endif
|
|
||||||
# Virtual Distributed Ethernet configuration
|
|
||||||
ifeq ($(vde),yes)
|
|
||||||
export CONFIG_AUTO_LKL_VIRTIO_NET_VDE=y
|
|
||||||
CFLAGS += -DCONFIG_AUTO_LKL_VIRTIO_NET_VDE
|
|
||||||
LDLIBS += $(shell pkg-config --libs vdeplug)
|
|
||||||
endif
|
|
||||||
else ifneq (,$(filter $(OUTPUT_FORMAT),pe-i386 pe-x86-64 ))
|
|
||||||
KOPT = "KALLSYMS_EXTRA_PASS=1"
|
|
||||||
LDLIBS += -lws2_32
|
|
||||||
EXESUF := .exe
|
|
||||||
SOSUF := .dll
|
|
||||||
export CONFIG_AUTO_LKL_NT_HOST=y
|
|
||||||
CFLAGS += -DCONFIG_AUTO_LKL_NT_HOST -Iinclude/mingw32
|
|
||||||
ifneq (,$(filter $(OUTPUT_FORMAT),pe-x86-64))
|
|
||||||
CFLAGS += -Wl,--enable-auto-image-base -Wl,--image-base -Wl,0x10000000 -Wl,--out-implib=$(OUTPUT)liblkl.dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import
|
|
||||||
LDFLAGS +=-Wl,--image-base -Wl,0x10000000 -Wl,--enable-auto-image-base -Wl,--out-implib=$(OUTPUT)liblkl.dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
$(error Unrecognized platform: $(OUTPUT_FORMAT))
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(OUTPUT),)
|
ifneq ($(OUTPUT),)
|
||||||
@@ -95,100 +18,73 @@ OUTPUT := $(CURDIR)/
|
|||||||
endif
|
endif
|
||||||
export OUTPUT
|
export OUTPUT
|
||||||
|
|
||||||
ifneq (,$(filter $(OUTPUT_FORMAT),pe-i386 pe-x86-64 ))
|
PREFIX := /usr
|
||||||
ALL_PROGRAMS :=
|
|
||||||
ALL_LIBRARIES := $(OUTPUT)liblkl.a $(OUTPUT)liblkl$(SOSUF)
|
ifeq (,$(srctree))
|
||||||
else
|
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||||
ALL_PROGRAMS := $(OUTPUT)lklfuse$(EXESUF) $(OUTPUT)cptofs$(EXESUF) $(OUTPUT)cpfromfs$(EXESUF) $(OUTPUT)fs2tar$(EXESUF)
|
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||||
ALL_LIBRARIES := $(OUTPUT)liblkl.a $(OUTPUT)liblkl$(SOSUF) $(OUTPUT)liblkl-hijack$(SOSUF)
|
|
||||||
endif
|
endif
|
||||||
|
export srctree
|
||||||
|
|
||||||
static: $(OUTPUT)liblkl.a
|
-include ../scripts/Makefile.include
|
||||||
shared: $(OUTPUT)liblkl$(SOSUF)
|
|
||||||
hijack: $(OUTPUT)liblkl-hijack$(SOSUF)
|
|
||||||
|
|
||||||
$(OUTPUT)liblkl$(SOSUF): $(OUTPUT)lib/lkl-in.o $(OUTPUT)lib/lkl.o
|
all:
|
||||||
$(OUTPUT)liblkl$(SOSUF): LDFLAGS += -shared
|
|
||||||
|
|
||||||
$(OUTPUT)liblkl-hijack$(SOSUF): $(OUTPUT)lib/hijack/hijack-in.o $(OUTPUT)liblkl.a
|
conf: $(OUTPUT)Makefile.conf
|
||||||
$(OUTPUT)liblkl-hijack$(SOSUF): LDFLAGS += -shared -nodefaultlibs
|
|
||||||
$(OUTPUT)liblkl-hijack$(SOSUF): LDLIBS += -ldl
|
|
||||||
ifneq (,$(filter $(OUTPUT_DEF),__ANDROID__))
|
|
||||||
$(OUTPUT)liblkl-hijack$(SOSUF): LDLIBS += -lgcc -lc
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(OUTPUT)lklfuse$(EXESUF): $(OUTPUT)lklfuse-in.o $(OUTPUT)liblkl.a
|
$(OUTPUT)Makefile.conf: Makefile.autoconf
|
||||||
$(OUTPUT)lklfuse$(EXESUF): LDLIBS += -lfuse
|
$(call QUIET_AUTOCONF, headers)$(MAKE) -f Makefile.autoconf -s
|
||||||
|
|
||||||
$(OUTPUT)fs2tar$(EXESUF): $(OUTPUT)fs2tar-in.o $(OUTPUT)liblkl.a
|
-include $(OUTPUT)Makefile.conf
|
||||||
$(OUTPUT)fs2tar$(EXESUF): LDLIBS += -larchive
|
|
||||||
ifneq (,$(filter $(OUTPUT_FORMAT),elf64-x86-64-freebsd pe-x86-64))
|
|
||||||
$(OUTPUT)fs2tar$(EXESUF): LDLIBS += -largp
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(OUTPUT)cptofs$(EXESUF): $(OUTPUT)cptofs-in.o $(OUTPUT)liblkl.a
|
export CFLAGS += -I$(OUTPUT)/include -Iinclude -Wall -g -O2 -Wextra \
|
||||||
ifneq (,$(filter $(OUTPUT_FORMAT),elf64-x86-64-freebsd))
|
-Wno-unused-parameter \
|
||||||
$(OUTPUT)cptofs$(EXESUF): LDLIBS += -largp
|
-Wno-missing-field-initializers -fno-strict-aliasing
|
||||||
endif
|
|
||||||
|
|
||||||
|
-include Targets
|
||||||
|
|
||||||
TEST_TARGETS := test valgrind gdb
|
TARGETS := $(progs-y:%=$(OUTPUT)%$(EXESUF))
|
||||||
|
TARGETS += $(libs-y:%=$(OUTPUT)%$(SOSUF))
|
||||||
$(OUTPUT)tests/boot: $(OUTPUT)tests/boot-in.o $(OUTPUT)liblkl.a
|
all: $(TARGETS)
|
||||||
ifneq (,$(filter $(OUTPUT_DEF),__ANDROID__))
|
|
||||||
$(OUTPUT)tests/boot: LDLIBS += -lc
|
|
||||||
endif
|
|
||||||
$(OUTPUT)tests/net-test: $(OUTPUT)tests/net-test-in.o $(OUTPUT)liblkl.a
|
|
||||||
$(OUTPUT)tests/disk: $(OUTPUT)tests/disk-in.o $(OUTPUT)liblkl.a
|
|
||||||
$(TEST_TARGETS): $(OUTPUT)tests/boot $(OUTPUT)tests/net-test $(OUTPUT)tests/disk
|
|
||||||
|
|
||||||
# because of libdl, liblkl-hijack will not compile on windows
|
|
||||||
# fortunately, the test target will handle a missing libhijack.so correctly
|
|
||||||
ifeq (,$(filter $(OUTPUT_FORMAT),pe-i386))
|
|
||||||
test: liblkl-hijack$(SOSUF)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(OUTPUT)%-in.o: $(OUTPUT)lib/lkl.o FORCE
|
|
||||||
$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(patsubst %/,%,$(dir $*)) obj=$(notdir $*)
|
|
||||||
|
|
||||||
|
# rule to build lkl.o
|
||||||
$(OUTPUT)lib/lkl.o:
|
$(OUTPUT)lib/lkl.o:
|
||||||
$(Q)$(MAKE) -C ../.. ARCH=lkl $(KOPT) defconfig
|
$(Q)$(MAKE) -C ../.. ARCH=lkl $(KOPT) defconfig
|
||||||
# this workaround is for arm32 linker (ld.gold)
|
# this workaround is for arm32 linker (ld.gold)
|
||||||
$(Q)export PATH=$(srctree)/tools/lkl/bin/:${PATH} ;\
|
$(Q)export PATH=$(srctree)/tools/lkl/bin/:${PATH} ;\
|
||||||
$(MAKE) -C ../.. ARCH=lkl $(KOPT) install INSTALL_PATH=$(OUTPUT)
|
$(MAKE) -C ../.. ARCH=lkl $(KOPT) install INSTALL_PATH=$(OUTPUT)
|
||||||
|
|
||||||
$(OUTPUT)liblkl.a: $(OUTPUT)lib/lkl-in.o $(OUTPUT)lib/lkl.o
|
# rules to link libs
|
||||||
|
$(OUTPUT)%$(SOSUF): LDFLAGS += -shared
|
||||||
|
$(OUTPUT)%$(SOSUF): $(OUTPUT)%-in.o $(OUTPUT)liblkl.a
|
||||||
|
$(QUIET_LINK)$(CC) $(LDFLAGS) $(LDFLAGS_$*-y) -o $@ $^ $(LDLIBS) $(LDLIBS_$*-y)
|
||||||
|
|
||||||
|
# liblkl is special
|
||||||
|
$(OUTPUT)liblkl$(SOSUF): $(OUTPUT)%-in.o $(OUTPUT)lib/lkl.o
|
||||||
|
$(OUTPUT)liblkl.a: $(OUTPUT)lib/liblkl-in.o $(OUTPUT)lib/lkl.o
|
||||||
$(QUIET_AR)$(AR) -rc $@ $^
|
$(QUIET_AR)$(AR) -rc $@ $^
|
||||||
|
|
||||||
$(OUTPUT)liblkl$(SOSUF) $(OUTPUT)liblkl-hijack$(SOSUF) $(OUTPUT)lklfuse$(EXESUF) $(OUTPUT)fs2tar$(EXESUF) $(OUTPUT)cptofs$(EXESUF) $(OUTPUT)tests/boot $(OUTPUT)tests/net-test $(OUTPUT)tests/disk:
|
# rule to link programs
|
||||||
$(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
$(OUTPUT)%$(EXESUF): $(OUTPUT)%-in.o $(OUTPUT)liblkl.a
|
||||||
|
$(QUIET_LINK)$(CC) $(LDFLAGS) $(LDFLAGS_$*-y) -o $@ $^ $(LDLIBS) $(LDLIBS_$*-y)
|
||||||
|
|
||||||
|
# rule to build objects
|
||||||
|
$(OUTPUT)%-in.o: $(OUTPUT)lib/lkl.o FORCE
|
||||||
|
$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(patsubst %/,%,$(dir $*)) obj=$(notdir $*)
|
||||||
|
|
||||||
|
|
||||||
$(OUTPUT)cpfromfs$(EXESUF): cptofs$(EXESUF)
|
$(OUTPUT)cpfromfs$(EXESUF): cptofs$(EXESUF)
|
||||||
$(Q)if ! [ -e $@ ]; then ln -s $< $@; fi
|
$(Q)if ! [ -e $@ ]; then ln -s $< $@; fi
|
||||||
|
|
||||||
# because of argp and fuse, none of the binaries will compile on windows
|
|
||||||
# because of libdl, liblkl-hijack will not compile on windows
|
|
||||||
# arm-android neither for the moment
|
|
||||||
ifneq (,$(filter $(OUTPUT_FORMAT),pe-i386))
|
|
||||||
all: $(filter-out $(OUTPUT)liblkl-hijack$(SOSUF), $(ALL_LIBRARIES))
|
|
||||||
else ifneq (,$(filter $(OUTPUT_DEF),__ANDROID__))
|
|
||||||
all: $(ALL_LIBRARIES)
|
|
||||||
else
|
|
||||||
all: $(ALL_PROGRAMS) $(ALL_LIBRARIES)
|
|
||||||
endif
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(call QUIET_CLEAN, objects)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd'\
|
$(call QUIET_CLEAN, objects)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd'\
|
||||||
-delete -o -name '\.*.d' -delete
|
-delete -o -name '\.*.d' -delete
|
||||||
$(call QUIET_CLEAN, headers)$(RM) -r $(OUTPUT)/include/lkl/
|
$(call QUIET_CLEAN, headers)$(RM) -r $(OUTPUT)/include/lkl/
|
||||||
$(call QUIET_CLEAN, "host libraries")$(RM) $(OUTPUT)/liblkl.a liblkl$(SOSUF)
|
$(call QUIET_CLEAN, liblkl.a)$(RM) $(OUTPUT)/liblkl.a
|
||||||
$(call QUIET_CLEAN, "hijack library")$(RM) $(OUTPUT)/liblkl-hijack$(SOSUF)
|
$(call QUIET_CLEAN, targets)$(RM) $(TARGETS)
|
||||||
$(call QUIET_CLEAN, programs)$(RM) $(ALL_PROGRAMS)
|
|
||||||
$(call QUIET_CLEAN, tests)$(RM) tests/boot tests/net-test tests/disk
|
|
||||||
|
|
||||||
$(TEST_TARGETS):
|
|
||||||
$(MAKE) -C tests $@
|
|
||||||
|
|
||||||
|
clean-conf: clean
|
||||||
|
$(call QUIET_CLEAN, Makefile.conf)$(RM) $(OUTPUT)/Makefile.conf
|
||||||
|
|
||||||
headers_install:
|
headers_install:
|
||||||
$(call QUIET_INSTALL, headers) \
|
$(call QUIET_INSTALL, headers) \
|
||||||
@@ -208,8 +104,14 @@ programs_install: $(ALL_PROGRAMS)
|
|||||||
|
|
||||||
install: headers_install libraries_install programs_install
|
install: headers_install libraries_install programs_install
|
||||||
|
|
||||||
|
TEST_TARGETS := test valgrind gdb
|
||||||
|
|
||||||
|
$(TEST_TARGETS):
|
||||||
|
$(MAKE) -C tests $@
|
||||||
|
|
||||||
FORCE: ;
|
FORCE: ;
|
||||||
.PHONY: all clean $(TEST_TARGETS) FORCE
|
.PHONY: all clean FORCE
|
||||||
.PHONY: headers_install libraries_install programs_install install
|
.PHONY: headers_install libraries_install programs_install install
|
||||||
.NOTPARALLEL : lib/lkl.o
|
.NOTPARALLEL : lib/lkl.o
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
|||||||
91
tools/lkl/Makefile.autoconf
Normal file
91
tools/lkl/Makefile.autoconf
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
POSIX_HOSTS=elf64-x86-64 elf32-i386 elf64-x86-64-freebsd elf32-littlearm elf64-littleaarch64
|
||||||
|
NT_HOSTS=pe-i386 pe-x86-64
|
||||||
|
|
||||||
|
define set_autoconf_var
|
||||||
|
$(file >> $(OUTPUT)/include/autoconf.h,#define LKL_HOST_CONFIG_$(1) $(2))
|
||||||
|
$(file >> $(OUTPUT)/tests/autoconf.sh,LKL_HOST_CONFIG_$(1)=$(2))
|
||||||
|
export LKL_HOST_CONFIG_$(1)=$(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define find_include
|
||||||
|
$(eval include_paths=$(shell $(CC) -E -Wp,-v -xc /dev/null 2>&1 | grep '^ '))
|
||||||
|
$(foreach f, $(include_paths), $(wildcard $(f)/$(1)))
|
||||||
|
endef
|
||||||
|
|
||||||
|
define is_defined
|
||||||
|
$(shell $(CC) -dM -E - </dev/null | grep $(1))
|
||||||
|
endef
|
||||||
|
|
||||||
|
define android_host
|
||||||
|
$(call set_autoconf_var,ANDROID,y)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define virtio_net_dpdk
|
||||||
|
$(call set_autoconf_var,VIRTIO_NET_DPDK,y)
|
||||||
|
RTE_SDK ?= $(OUTPUT)/dpdk-17.02
|
||||||
|
RTE_TARGET ?= build
|
||||||
|
DPDK_LIBS = -lrte_pmd_vmxnet3_uio -lrte_pmd_ixgbe -lrte_pmd_e1000
|
||||||
|
DPDK_LIBS += -lrte_pmd_virtio
|
||||||
|
DPDK_LIBS += -lrte_timer -lrte_hash -lrte_mbuf -lrte_ethdev -lrte_eal
|
||||||
|
DPDK_LIBS += -lrte_mempool -lrte_ring -lrte_pmd_ring
|
||||||
|
DPDK_LIBS += -lrte_kvargs -lrte_net
|
||||||
|
CFLAGS += -I$$(RTE_SDK)/$$(RTE_TARGET)/include -msse4.2 -mpopcnt
|
||||||
|
LDFLAGS +=-L$$(RTE_SDK)/$$(RTE_TARGET)/lib
|
||||||
|
LDFLAGS +=-Wl,--whole-archive $$(DPDK_LIBS) -Wl,--no-whole-archive -lm -ldl
|
||||||
|
endef
|
||||||
|
|
||||||
|
define virtio_net_vde
|
||||||
|
$(call set_autoconf_var,VIRTIO_NET_VDE,y)
|
||||||
|
LDLIBS += $(shell pkg-config --libs vdeplug)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define posix_host
|
||||||
|
$(call set_autoconf_var,POSIX,y)
|
||||||
|
$(call set_autoconf_var,VIRTIO_NET,y)
|
||||||
|
LDFLAGS += -pie
|
||||||
|
CFLAGS += -fPIC -pthread
|
||||||
|
SOSUF := .so
|
||||||
|
$(if $(call is_defined,__ANDROID__),$(call android_host),LDLIBS += -lrt -lpthread)
|
||||||
|
$(if $(filter yes,$(dpdk)),$(call virtio_net_dpdk))
|
||||||
|
$(if $(filter yes,$(vde)),$(call virtio_net_vde))
|
||||||
|
$(if $(strip $(call find_include,fuse.h)),$(call set_autoconf_var,FUSE,y))
|
||||||
|
$(if $(strip $(call find_include,archive.h)),$(call set_autoconf_var,ARCHIVE,y))
|
||||||
|
$(if $(filter $(1),elf64-x86-64-freebsd),$(call set_autoconf_var,NEEDS_LARGP,y))
|
||||||
|
endef
|
||||||
|
|
||||||
|
define nt64_host
|
||||||
|
$(call set_autoconf_var,NEEDS_LARGP,y)
|
||||||
|
CFLAGS += -Wl,--enable-auto-image-base -Wl,--image-base -Wl,0x10000000 \
|
||||||
|
-Wl,--out-implib=$(OUTPUT)liblkl.dll.a -Wl,--export-all-symbols \
|
||||||
|
-Wl,--enable-auto-import
|
||||||
|
LDFLAGS +=-Wl,--image-base -Wl,0x10000000 -Wl,--enable-auto-image-base \
|
||||||
|
-Wl,--out-implib=$(OUTPUT)liblkl.dll.a -Wl,--export-all-symbols \
|
||||||
|
-Wl,--enable-auto-import
|
||||||
|
endef
|
||||||
|
|
||||||
|
define nt_host
|
||||||
|
$(call set_autoconf_var,NT,y)
|
||||||
|
KOPT = "KALLSYMS_EXTRA_PASS=1"
|
||||||
|
LDLIBS += -lws2_32
|
||||||
|
EXESUF := .exe
|
||||||
|
SOSUF := .dll
|
||||||
|
CFLAGS += -Iinclude/mingw32
|
||||||
|
$(if $(filter $(1),pe-x86-64),$(call nt64_host))
|
||||||
|
endef
|
||||||
|
|
||||||
|
define do_autoconf
|
||||||
|
export CROSS_COMPILE := $(CROSS_COMPILE)
|
||||||
|
export CC := $(CROSS_COMPILE)gcc
|
||||||
|
export LD := $(CROSS_COMPILE)ld
|
||||||
|
export AR := $(CROSS_COMPILE)ar
|
||||||
|
$(eval LD := $(CROSS_COMPILE)ld)
|
||||||
|
$(eval CC := $(CROSS_COMPILE)gcc)
|
||||||
|
$(eval LD_FMT := $(shell $(LD) -r -print-output-format))
|
||||||
|
$(if $(filter $(LD_FMT),$(POSIX_HOSTS)),$(call posix_host,$(LD_FMT)))
|
||||||
|
$(if $(filter $(LD_FMT),$(NT_HOSTS)),$(call nt_host,$(LD_FMT)))
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(OUTPUT)Makefile.conf: Makefile.autoconf
|
||||||
|
$(file > $(OUTPUT)/include/autoconf.h)
|
||||||
|
$(file > $(OUTPUT)/tests/autoconf.sh)
|
||||||
|
$(file > $(OUTPUT)/Makefile.conf,$(call do_autoconf))
|
||||||
23
tools/lkl/Targets
Normal file
23
tools/lkl/Targets
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
libs-y += lib/liblkl
|
||||||
|
|
||||||
|
libs-$(LKL_HOST_CONFIG_POSIX) += lib/hijack/liblkl-hijack
|
||||||
|
LDFLAGS_lib/hijack/liblkl-hijack-y += -shared -nodefaultlibs
|
||||||
|
LDLIBS_lib/hijack/liblkl-hijack-y += -ldl
|
||||||
|
LDLIBS_lib/hijack/liblkl-hijack-$(LKL_HOST_CONFIG_ANDROID) += -lgcc -lc
|
||||||
|
|
||||||
|
progs-$(LKL_HOST_CONFIG_FUSE) += lklfuse
|
||||||
|
LDLIBS_lklfuse-y := -lfuse
|
||||||
|
|
||||||
|
progs-$(LKL_HOST_CONFIG_ARCHIVE) += fs2tar
|
||||||
|
LDLIBS_fs2tar-y := -larchive
|
||||||
|
LDLIBS_fs2tar-$(LKL_HOST_CONFIG_NEEDS_LARGP) += -largs
|
||||||
|
|
||||||
|
|
||||||
|
progs-$(LKL_HOST_CONFIG_ARCHIVE) += cptofs
|
||||||
|
LDLIBS_cptofs-y := -larchive
|
||||||
|
LDLIBS_cptofs-$(LKL_HOST_CONFIG_NEEDS_LARGP) += -largs
|
||||||
|
|
||||||
|
progs-y += tests/boot
|
||||||
|
progs-y += tests/disk
|
||||||
|
progs-y += tests/net-test
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
|
script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
|
||||||
|
|
||||||
export LD_LIBRARY_PATH=${script_dir}/../
|
export LD_LIBRARY_PATH=${script_dir}/../lib/hijack
|
||||||
if [ -n ${LKL_HIJACK_DEBUG+x} ]
|
if [ -n ${LKL_HIJACK_DEBUG+x} ]
|
||||||
then
|
then
|
||||||
trap '' TSTP
|
trap '' TSTP
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _LKL_H
|
#ifndef _LKL_H
|
||||||
#define _LKL_H
|
#define _LKL_H
|
||||||
|
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -386,8 +388,15 @@ struct lkl_netdev_args {
|
|||||||
* @returns a network device id (0 is valid) or a strictly negative value in
|
* @returns a network device id (0 is valid) or a strictly negative value in
|
||||||
* case of error
|
* case of error
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args* args);
|
int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args* args);
|
||||||
|
#else
|
||||||
|
static inline int lkl_netdev_add(struct lkl_netdev *nd,
|
||||||
|
struct lkl_netdev_args *args)
|
||||||
|
{
|
||||||
|
return -LKL_ENOSYS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_remove - remove a previously added network device
|
* lkl_netdev_remove - remove a previously added network device
|
||||||
@@ -397,14 +406,26 @@ int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args* args);
|
|||||||
*
|
*
|
||||||
* @id - the network device id, as return by @lkl_netdev_add
|
* @id - the network device id, as return by @lkl_netdev_add
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
void lkl_netdev_remove(int id);
|
void lkl_netdev_remove(int id);
|
||||||
|
#else
|
||||||
|
static inline void lkl_netdev_remove(int id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_free - frees a network device
|
* lkl_netdev_free - frees a network device
|
||||||
*
|
*
|
||||||
* @nd - the network device to free
|
* @nd - the network device to free
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
void lkl_netdev_free(struct lkl_netdev *nd);
|
void lkl_netdev_free(struct lkl_netdev *nd);
|
||||||
|
#else
|
||||||
|
static inline void lkl_netdev_free(struct lkl_netdev *nd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_get_ifindex - retrieve the interface index for a given network
|
* lkl_netdev_get_ifindex - retrieve the interface index for a given network
|
||||||
@@ -422,7 +443,15 @@ int lkl_netdev_get_ifindex(int id);
|
|||||||
* on host in advance
|
* on host in advance
|
||||||
* @offload - offload bits for the device
|
* @offload - offload bits for the device
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
struct lkl_netdev *lkl_netdev_tap_create(const char *ifname, int offload);
|
struct lkl_netdev *lkl_netdev_tap_create(const char *ifname, int offload);
|
||||||
|
#else
|
||||||
|
static inline struct lkl_netdev *
|
||||||
|
lkl_netdev_tap_create(const char *ifname, int offload)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_dpdk_create - create DPDK net_device for the virtio net backend
|
* lkl_netdev_dpdk_create - create DPDK net_device for the virtio net backend
|
||||||
@@ -432,8 +461,16 @@ struct lkl_netdev *lkl_netdev_tap_create(const char *ifname, int offload);
|
|||||||
* @offload - offload bits for the device
|
* @offload - offload bits for the device
|
||||||
* @mac - mac address pointer of dpdk-ed device
|
* @mac - mac address pointer of dpdk-ed device
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET_DPDK
|
||||||
struct lkl_netdev *lkl_netdev_dpdk_create(const char *ifname, int offload,
|
struct lkl_netdev *lkl_netdev_dpdk_create(const char *ifname, int offload,
|
||||||
unsigned char *mac);
|
unsigned char *mac);
|
||||||
|
#else
|
||||||
|
static inline struct lkl_netdev *
|
||||||
|
lkl_netdev_dpdk_create(const char *ifname, int offload, unsigned char *mac)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_vde_create - create VDE net_device for the virtio net backend
|
* lkl_netdev_vde_create - create VDE net_device for the virtio net backend
|
||||||
@@ -441,7 +478,14 @@ struct lkl_netdev *lkl_netdev_dpdk_create(const char *ifname, int offload,
|
|||||||
* @switch_path - path to the VDE switch directory. Needs to be started on host
|
* @switch_path - path to the VDE switch directory. Needs to be started on host
|
||||||
* in advance.
|
* in advance.
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET_VDE
|
||||||
struct lkl_netdev *lkl_netdev_vde_create(const char *switch_path);
|
struct lkl_netdev *lkl_netdev_vde_create(const char *switch_path);
|
||||||
|
#else
|
||||||
|
static inline struct lkl_netdev *lkl_netdev_vde_create(const char *switch_path)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_raw_create - create raw socket net_device for the virtio net
|
* lkl_netdev_raw_create - create raw socket net_device for the virtio net
|
||||||
@@ -449,7 +493,14 @@ struct lkl_netdev *lkl_netdev_vde_create(const char *switch_path);
|
|||||||
*
|
*
|
||||||
* @ifname - interface name for the snoop device.
|
* @ifname - interface name for the snoop device.
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
struct lkl_netdev *lkl_netdev_raw_create(const char *ifname);
|
struct lkl_netdev *lkl_netdev_raw_create(const char *ifname);
|
||||||
|
#else
|
||||||
|
static inline struct lkl_netdev *lkl_netdev_raw_create(const char *ifname)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_macvtap_create - create macvtap net_device for the virtio
|
* lkl_netdev_macvtap_create - create macvtap net_device for the virtio
|
||||||
@@ -459,7 +510,15 @@ struct lkl_netdev *lkl_netdev_raw_create(const char *ifname);
|
|||||||
* on host in advance
|
* on host in advance
|
||||||
* @offload - offload bits for the device
|
* @offload - offload bits for the device
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
struct lkl_netdev *lkl_netdev_macvtap_create(const char *path, int offload);
|
struct lkl_netdev *lkl_netdev_macvtap_create(const char *path, int offload);
|
||||||
|
#else
|
||||||
|
static inline struct lkl_netdev *
|
||||||
|
lkl_netdev_macvtap_create(const char *path, int offload)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lkl_netdev_pipe_create - create pipe net_device for the virtio
|
* lkl_netdev_pipe_create - create pipe net_device for the virtio
|
||||||
@@ -469,7 +528,15 @@ struct lkl_netdev *lkl_netdev_macvtap_create(const char *path, int offload);
|
|||||||
* on host in advance. delimiter is "|". e.g. "rx_name|tx_name".
|
* on host in advance. delimiter is "|". e.g. "rx_name|tx_name".
|
||||||
* @offload - offload bits for the device
|
* @offload - offload bits for the device
|
||||||
*/
|
*/
|
||||||
|
#ifdef LKL_HOST_CONFIG_VIRTIO_NET
|
||||||
struct lkl_netdev *lkl_netdev_pipe_create(const char *ifname, int offload);
|
struct lkl_netdev *lkl_netdev_pipe_create(const char *ifname, int offload);
|
||||||
|
#else
|
||||||
|
static inline struct lkl_netdev *
|
||||||
|
lkl_netdev_pipe_create(const char *ifname, int offload)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lkl_register_dbg_handler- register a signal handler that loads a debug lib.
|
* lkl_register_dbg_handler- register a signal handler that loads a debug lib.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ int lkl_printf(const char *fmt, ...);
|
|||||||
|
|
||||||
extern char lkl_virtio_devs[4096];
|
extern char lkl_virtio_devs[4096];
|
||||||
|
|
||||||
#ifdef CONFIG_AUTO_LKL_POSIX_HOST
|
#ifdef LKL_HOST_CONFIG_POSIX
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#else
|
#else
|
||||||
struct iovec {
|
struct iovec {
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
|
|||||||
CFLAGS_virtio_net_vde.o += $(pkg-config --cflags vdeplug 2>/dev/null)
|
CFLAGS_virtio_net_vde.o += $(pkg-config --cflags vdeplug 2>/dev/null)
|
||||||
CFLAGS_nt-host.o += -D_WIN32_WINNT=0x0600
|
CFLAGS_nt-host.o += -D_WIN32_WINNT=0x0600
|
||||||
|
|
||||||
lkl-y += fs.o
|
liblkl-y += fs.o
|
||||||
lkl-y += iomem.o
|
liblkl-y += iomem.o
|
||||||
lkl-y += net.o
|
liblkl-y += net.o
|
||||||
lkl-y += jmp_buf.o
|
liblkl-y += jmp_buf.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += posix-host.o
|
liblkl-$(LKL_HOST_CONFIG_POSIX) += posix-host.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_NT_HOST) += nt-host.o
|
liblkl-$(LKL_HOST_CONFIG_NT) += nt-host.o
|
||||||
lkl-y += utils.o
|
liblkl-y += utils.o
|
||||||
lkl-y += virtio_blk.o
|
liblkl-y += virtio_blk.o
|
||||||
lkl-y += virtio.o
|
liblkl-y += virtio.o
|
||||||
lkl-y += dbg.o
|
liblkl-y += dbg.o
|
||||||
lkl-y += dbg_handler.o
|
liblkl-y += dbg_handler.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_fd.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_fd.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_tap.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_tap.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_raw.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_raw.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_macvtap.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_macvtap.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_dpdk.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET_DPDK) += virtio_net_dpdk.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_vde.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET_VDE) += virtio_net_vde.o
|
||||||
lkl-$(CONFIG_AUTO_LKL_POSIX_HOST) += virtio_net_pipe.o
|
liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_pipe.o
|
||||||
lkl-y += ../../perf/pmu-events/jsmn.o
|
liblkl-y += ../../perf/pmu-events/jsmn.o
|
||||||
lkl-y += config.o
|
liblkl-y += config.o
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
hijack-y += hijack.o
|
liblkl-hijack-y += hijack.o
|
||||||
hijack-y += init.o
|
liblkl-hijack-y += init.o
|
||||||
hijack-y += xlate.o
|
liblkl-hijack-y += xlate.o
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef CONFIG_AUTO_LKL_VIRTIO_NET_DPDK
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -478,15 +477,3 @@ struct lkl_netdev *lkl_netdev_dpdk_create(const char *ifparams, int offload,
|
|||||||
|
|
||||||
return (struct lkl_netdev *) nd;
|
return (struct lkl_netdev *) nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
struct lkl_netdev *lkl_netdev_dpdk_create(const char *ifparams, int offload,
|
|
||||||
unsigned char *mac)
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"lkl: dpdk is not built. please build LKL to enable dpdk.\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_AUTO_LKL_VIRTIO_NET_DPDK */
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef CONFIG_AUTO_LKL_VIRTIO_NET_VDE
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -166,13 +165,3 @@ struct lkl_netdev *lkl_netdev_vde_create(char const *switch_path)
|
|||||||
|
|
||||||
return &nd->dev;
|
return &nd->dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_AUTO_LKL_VIRTIO_NET_VDE */
|
|
||||||
|
|
||||||
struct lkl_netdev *lkl_netdev_vde_create(char const *switch_path)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "lkl: The host library was compiled without support for VDE networking. Please rebuild with VDE enabled.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_AUTO_LKL_VIRTIO_NET_VDE */
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|||||||
export PATH=${script_dir}:${PATH}
|
export PATH=${script_dir}:${PATH}
|
||||||
export LKL_ANDROID_TEST=1
|
export LKL_ANDROID_TEST=1
|
||||||
export TMPDIR=/data/local/tmp
|
export TMPDIR=/data/local/tmp
|
||||||
export CONFIG_AUTO_LKL_POSIX_HOST=y
|
export LKL_CONFIG_POSIX_HOST=y
|
||||||
export LKL_TEST_DHCP=1
|
export LKL_TEST_DHCP=1
|
||||||
|
|
||||||
sed -i "s/\/bin\/bash/\/system\/bin\/sh /" ${script_dir}/../bin/lkl-hijack.sh
|
sed -i "s/\/bin\/bash/\/system\/bin\/sh /" ${script_dir}/../bin/lkl-hijack.sh
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ addr=$(LKL_HIJACK_CONFIG_FILE=$cfgjson \
|
|||||||
echo "$addr" | grep fc04::
|
echo "$addr" | grep fc04::
|
||||||
echo "$addr" | grep fc04::1
|
echo "$addr" | grep fc04::1
|
||||||
|
|
||||||
if [ -z "`printenv CONFIG_AUTO_LKL_VIRTIO_NET_VDE`" ]; then
|
if [ -z "`printenv LKL_CONFIG_VIRTIO_NET_VDE`" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ echo "== Loopback (LKL net) tests =="
|
|||||||
./net-test --dst 127.0.0.1
|
./net-test --dst 127.0.0.1
|
||||||
|
|
||||||
# the rest of the tests are not supported on mingw
|
# the rest of the tests are not supported on mingw
|
||||||
if [ "`printenv CONFIG_AUTO_LKL_POSIX_HOST`" != "y" ] ; then
|
if [ "`printenv LKL_CONFIG_POSIX_HOST`" != "y" ] ; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user