精华内容
下载资源
问答
  • 【总结】嵌入式linux内核中Makefile、Kconfig、.config的关系及增加开机Hello World
    千次阅读
    2017-06-27 11:04:46

    为了弄清内核的组织结构,我们先来实现下面这个简单的例子。

    一、增加内核启动Hello World

    任务:

    内核启动的时候加载Hello驱动,并打印出Hello World

    步骤:

    (1)在drivers目录下新建hello文件夹,在里面实现相应的hello.c、Makefile、Kconfig

    (2)修改上一级(linux-3.4.2/drivers下)的Makefile、Kconfig

    (3)make menuconfig 进行配置

    (4)编译、烧写、运行

    实现:

    (1)实现驱动程序hello.c

    最简单的驱动程序

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/delay.h>
    static int first_drv_init(void)
    {
    	printk("------------------hello world !--------------------");
    	return 0;
    }
    
    static void first_drv_exit(void)
    {
    	printk("------------------exit hello world !--------------------");
    }
    
    module_init(first_drv_init);
    module_exit(first_drv_exit);
    
    
    MODULE_LICENSE("GPL");
    (2)实现 hello/Makefile
    # LED Core
    obj-$(CONFIG_HELLO)			+= hello.o

    注意这里的CONFIG_HELLO,是在.config中定义的,如果配置编译进内核,则在.config中出现CONFIG_HELLO=y,那么hello.o就会被编译进内核。

    (3)实现hello/Kconfig

    config HELLO
    	tristate "Hello World for fengyuwuzu"
    	help
    	  Hello  for fengyuwuzu

    config HELLO决定了CONFIG_HELLO这个名字

    Hello World for fengyuwuzu:决定了在make menuconfig时的GUI名字

    (4)修改drivers/Makefile,增加:

    obj-y                           += myled/
    (5) 修改 drivers/ Kconfig,增加:
    source "drivers/myled/Kconfig"
    (6)make menuconfig配置相应项进内核




    (7)make uImage

    (8)烧写新内核启动

    看到"------------------hello world !--------------------"被打印,及相应的驱动被加载。


    二、linux内核中Makefile、Kconfig、.config的关系

    (1)三者的作用

    简单来说就是去饭店点菜:Kconfig是菜单,Makefile是做法,.config就是你点的菜

    Makefile:一个文本形式的文件,编译源文件的方法。

    Kconfig:一个文本形式的文件,内核的配置菜单。

    .config:编译所依据的配置。

    (2)三者的语法

    1、Makefile

    目标定义:目标定义就是用来定义哪些内容要做为模块编译,哪些要编译链接进内核。

    直接编译:

    obj-y      += hello.o

    表示要由hello.c或者hello.s文件编译得到hello.o并链接进内核

    而更常见的做法是根据.config文件的CONFIG_ 变量来决定文件的编译方式 :

    条件编译:

    obj-$(CONFIG_HELLO) += hello.o

    obj-m则表示该文件要作为模块编译。

    除了y,m以外的obj-x形式的目标都不会被编译。

     

    2、Kconfig

    类型定义: 

    每个config菜单项都要有类型定义: bool布尔类型、 tristate三态(内建、模块、移除)、string字符串、 hex十六进制、integer整型。 
    例如: 
    config HELLO_MODULE 
    bool "hello test module" 
    bool 类型的只能选中或不选中,显示为[ ];

     tristate类型的菜单项多了编译成内核模块的选项,显示为< > , 假如选择编译成内核模块,则会在.config中生成一个 CONFIG_HELLO_MODULE=m的配置,假如选择内建,就是直接编译成内核影响,就会在.config中生成一个 CONFIG_HELLO_MODULE=y的配置. hex十六进制类型显示为( )。

    目录层次迭代 
    在Kconfig中有类似语句:source"drivers/usb/Kconfig" 
    用来包含(或嵌套)新的Kconfig文件,这样便可以使各个目录管理各自的配置内容,使不必把那些配置都写在同一个文件里,方便修改和管理。

     配置选项之间的依赖关系
     depend on:某选项依赖于另外一个选项生成
     select   :反向依赖关系,该选项选中时,同时选中select后面定义的那一项
     requie
     默认值: default(默认y/n/m等值)
     输入提示:prompt
     帮助信息:help



    3、.config

    内核编译参考文件。

    修改方式:

    (1)    make menuconfig

    (2)    make xxx_defconfig

    (3)    直接修改

    !注意如果直接修改,不一定会生效,因为一些配置可能存在依赖关系,make的时候会根据依赖关系,进行规则的检查,不推荐直接在.config进行修改。

    更多相关内容
  • 这六个因素并不是要被解释为特定的因果关系,而是要被理解为与一个国家的幸福和福祉相关的事实。 在新兴的幸福与幸福科学中,它们被视为值得信赖的指标。 (《 2019年世界幸福报告》常见问题解答) 目标: 我想...
  • gb-hello-world

    2021-04-04 16:09:40
    gb样板 用于Game Boy RGBDS项目的最小的,可定制的,易于编译的样板。... 如果要创建一个新的“模块”,只需要在src目录中放置一个.asm文件,名称就没有关系。 根目录中的所有.asm文件将由RGBASM单独编译。 src/re
  • hello-world:总体的目标

    2021-05-15 23:20:41
    我将通过以下步骤做到这一点:与个人和组织建立合作伙伴关系,以帮助每个人发展,增加其价值以及与之相关的收入。 提供体验式学习机会-学徒制和导师制(在从事实际工作的同时获得报酬)创建社区市场。 在这里,您...
  • 从懵懂的少年,到拿起键盘,可以写一个HelloWorld。多数人在这并不会感觉有多难,也不会认为不出来。因为这样的例子,有老师的指导、有书本的例子、有前人的经验。但随着你的开发时间越来越长,要解决更复杂的问题...


    作者:小傅哥
    博客:https://bugstack.cn - 原创系列专题文章

    沉淀、分享、成长,让自己和他人都能有所收获!😄

    一、前言

    相信相信的力量!

    从懵懂的少年,到拿起键盘,可以写一个HelloWorld。多数人在这并不会感觉有多难,也不会认为做不出来。因为这样的例子,有老师的指导、有书本的例子、有前人的经验。但随着你的开发时间越来越长,要解决更复杂的问题或者技术创新,因此在网上搜了几天几夜都没有答案,这个时候是否想过放弃,还是一直坚持不断的尝试一点点完成自己心里要的结果。往往这种没有前车之鉴需要自己解决问题的时候,可能真的会折磨到要崩溃,但你要愿意执着、愿意倔强,愿意选择相信相信的力量,就一定能解决。哪怕解决不了,也可以在这条路上摸索出其他更多的收获,为后续前进的道路填充好垫脚石。

    时间紧是写垃圾代码的理由?

    拧螺丝?Ctrl+C、Ctrl+V?贴膏药一样写代码?没有办法,没有时间,往往真的是借口,胸中没用笔墨,才只能凑合。难道一定是好好写代码就浪费时间,拼凑CRUD就快吗,根本不可能的。因为不会,没用实操过,很少架构出全场景的设计,才很难写出优良的代码。多增强自身的编码(武术)修为,在各种编码场景中让自己变得老练,才好应对紧急情况下的需求开发和人员安排。就像韩信一样有谋有略,才能执掌百万雄兵。

    不要只是做个工具人!

    因为日常的编写简单业务需求,导致自己像个工具人一样,日久天长的也就很少去深入学习更多技术栈。看见有工具、有组件、有框架,拿来就用用,反正没什么体量也不会出什么问题。但如果你想要更多的收入,哪怕是重复的造轮子,你也要去尝试造一个,就算不用到生产,自己玩玩总可以吧。有些事情只有自己经历过,才能有最深的感触,参与过实践过,才好总结点评学习。

    二、开发环境

    1. JDK 1.8
    2. Idea + Maven
    3. 涉及工程一个,可以通过关注公众号bugstack虫洞栈,回复源码下载获取(打开获取的链接,找到序号18)
    工程描述
    itstack-demo-design-15-00开发树形组织架构关系迭代器

    三、迭代器模式介绍

    迭代器模式,图片来自 refactoringguru.cn

    迭代器模式,常见的就是我们日常使用的iterator遍历。虽然这个设计模式在我们的实际业务开发中的场景并不多,但却几乎每天都要使用jdk为我们提供的list集合遍历。另外增强的for循环虽然是循环输出数据,但是他不是迭代器模式。迭代器模式的特点是实现Iterable接口,通过next的方式获取集合元素,同时具备对元素的删除等操作。而增强的for循环是不可以的。

    这种设计模式的优点是可以让我们以相同的方式,遍历不同的数据结构元素,这些数据结构包括;数组链表等,而用户在使用遍历的时候并不需要去关心每一种数据结构的遍历处理逻辑,从让使用变得统一易用。

    四、案例场景模拟

    场景模拟;公司树形组织架构

    在本案例中我们模拟迭代遍历输出公司中树形结构的组织架构关系中雇员列表

    大部分公司的组织架构都是金字塔结构,也就这种树形结构,分为一级、二级、三级等部门,每个组织部门由雇员填充,最终体现出一个整体的树形组织架构关系。

    一般我们常用的遍历就是jdk默认提供的方法,对list集合遍历。但是对于这样的偏业务特性较大的树形结构,如果需要使用到遍历,那么就可以自己来实现。接下来我们会把这个组织层次关系通过树形数据结构来实现,并完成迭代器功能。

    五、迭代器模式遍历组织结构

    在实现迭代器模式之前可以先阅读下javalist方法关于iterator的实现部分,几乎所有的迭代器开发都会按照这个模式来实现,这个模式主要分为以下几块;

    1. Collection,集合方法部分用于对自定义的数据结构添加通用方法;addremoveiterator等核心方法。
    2. Iterable,提供获取迭代器,这个接口类会被Collection继承。
    3. Iterator,提供了两个方法的定义;hasNextnext,会在具体的数据结构中写实现方式。

    除了这样通用的迭代器实现方式外,我们的组织关系结构树,是由节点和节点间的关系链构成,所以会比上述的内容多一些入参。

    1. 工程结构

    itstack-demo-design-15-02
    └── src
        ├── main
        │   └── java
        │       └── org.itstack.demo.design
        │           ├── group
        │           │	├── Employee.java
        │           │	├── GroupStructure.java
        │           │	└── Link.java
        │           └──  lang
        │            	├── Collection.java
        │            	├── Iterable.java
        │            	└── Iterator.java
        └── test
            └── java
                └── org.itstack.demo.design.test
                    └── ApiTest.java
    

    迭代器模式模型结构

    迭代器模式模型结构

    • 以上是我们工程类图的模型结构,左侧是对迭代器的定义,右侧是在数据结构中实现迭代器功能。
    • 关于左侧部分的实现与jdk中的方式是一样的,所以在学习的过程中可以互相参考,也可以自己扩展学习。
    • 另外这个遍历方式一个树形结构的深度遍历,为了可以更加让学习的小伙伴容易理解,这里我实现了一种比较简单的树形结构深度遍历方式。后续读者也可以把遍历扩展为横向遍历也就是宽度遍历。

    2. 代码实现

    2.1 雇员实体类

    /**
     * 雇员
     */
    public class Employee {
    
        private String uId;   // ID
        private String name;  // 姓名
        private String desc;  // 备注
        
        // ...get/set
    }
    
    • 这是一个简单的雇员类,也就是公司员工的信息类,包括必要的信息;id、姓名、备注。

    2.2 树节点链路

    /**
     * 树节点链路
     */
    public class Link {
    
        private String fromId; // 雇员ID
        private String toId;   // 雇员ID    
        
        // ...get/set
    }
    
    • 这个类用于描述结构树中的各个节点之间的关系链,也就是A to BB to CB to D,以此描述出一套完整的树组织结构。

    2.3 迭代器定义

    public interface Iterator<E> {
    
        boolean hasNext();
    
        E next();
        
    }
    
    • 这里的这个类和javajdk中提供的是一样的,这样也方面后续读者可以对照listIterator进行源码学习。
    • 方法描述;hasNext,判断是否有下一个元素、next,获取下一个元素。这个在list的遍历中是经常用到的。

    2.4 可迭代接口定义

    public interface Iterable<E> {
    
        Iterator<E> iterator();
    
    }
    
    • 这个接口中提供了上面迭代器的实现Iterator的获取,也就是后续在自己的数据结构中需要实现迭代器的功能并交给Iterable,由此让外部调用方进行获取使用。

    2.5 集合功能接口定义

    public interface Collection<E, L> extends Iterable<E> {
    
        boolean add(E e);
    
        boolean remove(E e);
    
        boolean addLink(String key, L l);
    
        boolean removeLink(String key);
    
        Iterator<E> iterator();
    
    }
    
    • 这里我们定义集合操作接口;Collection,同时继承了另外一个接口Iterable的方法iterator()。这样后续谁来实现这个接口,就需要实现上述定义的一些基本功能;添加元素删除元素遍历
    • 同时你可能注意到这里定义了两个泛型<E, L>,因为我们的数据结构一个是用于添加元素,另外一个是用于添加树节点的链路关系。

    2.6 (核心)迭代器功能实现

    public class GroupStructure implements Collection<Employee, Link> {
    
        private String groupId;                                                 // 组织ID,也是一个组织链的头部ID
        private String groupName;                                               // 组织名称
        private Map<String, Employee> employeeMap = new ConcurrentHashMap<String, Employee>();  // 雇员列表
        private Map<String, List<Link>> linkMap = new ConcurrentHashMap<String, List<Link>>();  // 组织架构关系;id->list
        private Map<String, String> invertedMap = new ConcurrentHashMap<String, String>();       // 反向关系链
    
        public GroupStructure(String groupId, String groupName) {
            this.groupId = groupId;
            this.groupName = groupName;
        }
    
        public boolean add(Employee employee) {
            return null != employeeMap.put(employee.getuId(), employee);
        }
    
        public boolean remove(Employee o) {
            return null != employeeMap.remove(o.getuId());
        }
    
        public boolean addLink(String key, Link link) {
            invertedMap.put(link.getToId(), link.getFromId());
            if (linkMap.containsKey(key)) {
                return linkMap.get(key).add(link);
            } else {
                List<Link> links = new LinkedList<Link>();
                links.add(link);
                linkMap.put(key, links);
                return true;
            }
        }
    
        public boolean removeLink(String key) {
            return null != linkMap.remove(key);
        }
    
        public Iterator<Employee> iterator() {
    
            return new Iterator<Employee>() {
    
                HashMap<String, Integer> keyMap = new HashMap<String, Integer>();
    
                int totalIdx = 0;
                private String fromId = groupId;  // 雇员ID,From
                private String toId = groupId;   // 雇员ID,To
    
                public boolean hasNext() {
                    return totalIdx < employeeMap.size();
                }
    
                public Employee next() {
                    List<Link> links = linkMap.get(toId);
                    int cursorIdx = getCursorIdx(toId);
    
                    // 同级节点扫描
                    if (null == links) {
                        cursorIdx = getCursorIdx(fromId);
                        links = linkMap.get(fromId);
                    }
    
                    // 上级节点扫描
                    while (cursorIdx > links.size() - 1) {
                        fromId = invertedMap.get(fromId);
                        cursorIdx = getCursorIdx(fromId);
                        links = linkMap.get(fromId);
                    }
    
                    // 获取节点
                    Link link = links.get(cursorIdx);
                    toId = link.getToId();
                    fromId = link.getFromId();
                    totalIdx++;
    
                    // 返回结果
                    return employeeMap.get(link.getToId());
                }
                 
                // 给每个层级定义宽度遍历进度
                public int getCursorIdx(String key) {
                    int idx = 0;
                    if (keyMap.containsKey(key)) {
                        idx = keyMap.get(key);
                        keyMap.put(key, ++idx);
                    } else {
                        keyMap.put(key, idx);
                    }
                    return idx;
                }
            };
        }
    
    }
    
    • 以上的这部分代码稍微有点长,主要包括了对元素的添加和删除。另外最重要的是对遍历的实现new Iterator<Employee>
    • 添加和删除元素相对来说比较简单,使用了两个map数组结构进行定义;雇员列表组织架构关系;id->list。当元素添加元素的时候,会分别在不同的方法中向map结构中进行填充指向关系(A->B),也就构建出了我们的树形组织关系。

    迭代器实现思路

    1. 这里的树形结构我们需要做的是深度遍历,也就是左侧的一直遍历到最深节点。
    2. 当遍历到最深节点后,开始遍历最深节点的横向节点。
    3. 当横向节点遍历完成后则向上寻找横向节点,直至树结构全部遍历完成。

    3. 测试验证

    3.1 编写测试类

    @Test
    public void test_iterator() { 
        // 数据填充
        GroupStructure groupStructure = new GroupStructure("1", "小傅哥");  
        
        // 雇员信息
        groupStructure.add(new Employee("2", "花花", "二级部门"));
        groupStructure.add(new Employee("3", "豆包", "二级部门"));
        groupStructure.add(new Employee("4", "蹦蹦", "三级部门"));
        groupStructure.add(new Employee("5", "大烧", "三级部门"));
        groupStructure.add(new Employee("6", "虎哥", "四级部门"));
        groupStructure.add(new Employee("7", "玲姐", "四级部门"));
        groupStructure.add(new Employee("8", "秋雅", "四级部门"));   
        
        // 节点关系 1->(1,2) 2->(4,5)
        groupStructure.addLink("1", new Link("1", "2"));
        groupStructure.addLink("1", new Link("1", "3"));
        groupStructure.addLink("2", new Link("2", "4"));
        groupStructure.addLink("2", new Link("2", "5"));
        groupStructure.addLink("5", new Link("5", "6"));
        groupStructure.addLink("5", new Link("5", "7"));
        groupStructure.addLink("5", new Link("5", "8"));       
    
        Iterator<Employee> iterator = groupStructure.iterator();
        while (iterator.hasNext()) {
            Employee employee = iterator.next();
            logger.info("{},雇员 Id:{} Name:{}", employee.getDesc(), employee.getuId(), employee.getName());
        }
    }
    

    3.2 测试结果

    22:23:37.166 [main] INFO  org.itstack.demo.design.test.ApiTest - 二级部门,雇员 Id:2 Name:花花
    22:23:37.168 [main] INFO  org.itstack.demo.design.test.ApiTest - 三级部门,雇员 Id:4 Name:蹦蹦
    22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 三级部门,雇员 Id:5 Name:大烧
    22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 四级部门,雇员 Id:6 Name:虎哥
    22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 四级部门,雇员 Id:7 Name:玲姐
    22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 四级部门,雇员 Id:8 Name:秋雅
    22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 二级部门,雇员 Id:3 Name:豆包
    
    Process finished with exit code 0
    
    • 从遍历的结果可以看到,我们是顺着树形结构的深度开始遍历,一直到右侧的节点3雇员 Id:2、雇员 Id:4...雇员 Id:3

    六、总结

    • 迭代器的设计模式从以上的功能实现可以看到,满足了单一职责和开闭原则,外界的调用方也不需要知道任何一个不同的数据结构在使用上的遍历差异。可以非常方便的扩展,也让整个遍历变得更加干净整洁。
    • 但从结构的实现上可以看到,迭代器模式的实现过程相对来说是比较负责的,类的实现上也扩增了需要外部定义的类,使得遍历与原数据结构分开。虽然这是比较麻烦的,但可以看到在使用java的jdk时候,迭代器的模式还是很好用的,可以非常方便扩展和升级。
    • 以上的设计模式场景实现过程可能对新人有一些不好理解点,包括;迭代器三个和接口的定义、树形结构的数据关系、树结构深度遍历思路。这些都需要反复实现练习才能深入的理解,事必躬亲,亲历亲为,才能让自己掌握这些知识。

    七、推荐阅读

    展开全文
  • 该研究提出并检验了两个假设:a) 感知到的来自竞争对手的压力与 WHS 中的 ICT 使用之间存在显着关系,以及 b) 感知到的来自客户/访客的压力与 WHS 中的 ICT 使用之间存在显着关系。 方法:本研究的数据来自坦桑尼亚...
  • GOLAND建立HELLOWORLD项目

    千次阅读 2019-11-09 15:23:59
    1、一般来说,建议包名和目录名保持一致,所以,在src文件夹下,按照你想要创建的包名,组织文件夹路径。这里,我们在D:\GOBUILD\GOPATH\src下面,建立hello文件夹 关于包,根据本地测试得出以下几点: 文件名与...


    首先去官网下载go的安装包

    安装GO

    1 安装

    安装其实没有什么好说的,我们一路next,采用默认安装,安装在C:\Go下。在安装的时候,会自动在系统环境变量里新建一个 GOROOT 环境变量,还会自动把 PATH 环境变量设置好

    关于工作空间

    GO代码必须在工作空间内。
    工作空间是一个目录,其中包含三个子目录:
    src ---- 里面每一个子目录,就是一个包。包内是Go的源码文件
    pkg ---- 编译后生成的,包的目标文件
    bin ---- 生成的可执行文件。
    这里,我们建立D:\GOBUILD\GOPATH(可以不是GOPATH, 任意名字都可以)的文件夹,
    然后再建立三个子文件夹(子文件夹名必须为src、pkg、bin)。

    添加GOPATH环境变量

    安装包不会帮我们添加的,就是这个GOPATH环境变量了。
    我将变量值设为:【D:\GOBUILD\GOPATH

    关于goroot,gopath,gobin的作用:

    goroot一般是全局性的,gopath与gobin,通过环境变量设置可以设置全局gopath,在任意路径下执行go build,会优先查找全局gopath下的src目录内的go文件进行编译。go get命令也会将go编译过程中所需要的依赖包下载到gopath里(package目录),编译生成的exe文件,默认放在gopath的bin目录下。
    用goland工具建立的项目时,可以为每一个Project配置gopath目录,这个项目在编译时,如果按照package编译,会查找本项目内的package进行编译。

    GOROOT

    go的安装目录(/usr/local/go)

    GOPATH

    go工作环境中常常用到的一个很重要的环境变量。

    GOPATH的值可以是一个目录的路径,也可以是包含多个目录的路径,每个目录都代表Go语言的一个工作区(workspace)。一般情况下,为了分离自己与第三方的代码,我们会设置两个或更多的工作区。当有多个GOPATH时,默认会将go get的内容放在第一个目录下。

    工作区用于放置Go语言的源码文件,以及安装(install)后的归档文件(archive file,也就是以".a"为扩展名的文件)和可执行文件(executable file)。

    Go语言项目在其生命周期内的所有操作(编码,依赖管理,构建,测试,安装等)基本上都是围绕GOPATH和工作区进行的。

    Go 语言提供的很多工具都是在 GOPATH 和工作区的基础上运行的,例如go build,go install,go get。

    GOPATH约定有三个子目录
    src 存放源代码
    pkg 存放编译后生成的文件
    bin 编译后生成的可执行文件

    GOBIN

    不允许设置多个路径,可以不设置。为空时遵循约定由于配置原则,可执行文件放置各自GOPATH目录的bin文件夹中。

    当设置多个GOPATH时,可以用“export PATH= P A T H : PATH: PATH:{GOPATH//😕/bin:}/bin”把每个GOPATH下的bin都加入到PATH中。

    开始 HelloWorld

    新建项目(应用包)。

    1、一般来说,建议包名和目录名保持一致,所以,在src文件夹下,按照你想要创建的包名,组织文件夹路径。这里,我们在D:\GOBUILD\GOPATH\src下面,建立hello文件夹
    关于包,根据本地测试得出以下几点:
    文件名与包名没有直接关系,不一定要将文件名与包名定成同一个。
    文件夹名与包名没有直接关系,并非需要一致。
    同一个文件夹下的文件只能有一个包名,否则编译报错。

    2、新建go代码
    D:\GOBUILD\GOPATH\src\hello下面,建立helloworld.go文件,并编辑,加入如下代码:

    package main
    import(
     "fmt"
     "time"
    )
    
    func main() {
     fmt.Println("Hello world!")
     duration := time.Duration(10)*time.Second
     time.Sleep(duration)
    }
    

    3、编译生成go程序
    打开命令行,在任意文件路径下,运行:
    go install hello
    也可以进入项目(应用包)的路径,然后运行:
    go install
    在编译生成go程序的时,go实际上会去两个地方找程序包:
    GOROOT下的src文件夹下,以及GOPATH下的src文件夹下。

    在程序包里,自动找main包的main函数作为程序入口,然后进行编译。
    如果想编译不在全局gopath中的项目helloworld,直接用命令行在helloworld项目文件目录helloworld\src\main下执行:go install helloworld
    4、运行go程序
    在D:\gopath\bin\下,会发现出现了一个hello.exe的可执行文件,双击运行:
    OK!成功!运行10秒后,程序自动退出~

    go install 和go build

    go install/build都是用来编译包和其依赖的包。
    区别:
    go build只对main包有效,在当前目录编译生成一个可执行的二进制文件(依赖包生成的静态库文件放在 G O P A T H / p k g ) 。 g o i n s t a l l 一 般 生 成 静 态 库 文 件 放 在 GOPATH/pkg)。 go install一般生成静态库文件放在 GOPATH/pkggoinstallGOPATH/pkg目录下,文件扩展名a.只对main包有效,在当前目录编译生成一个可执行的二进制文件(依赖包生成的静态库文件放在 G O P A T H / p k g ) 。 g o i n s t a l l 一 般 生 成 静 态 库 文 件 放 在 GOPATH/pkg)。 go install一般生成静态库文件放在 GOPATH/pkggoinstallGOPATH/pkg目录下,文件扩展名a.如果为main包,则会在 G O P A T H / b i n 生 成 一 个 可 执 行 的 二 进 制 文 件 。 , 则 会 在 GOPATH/bin 生成一个可执行的二进制文件。,则会在 GOPATH/binGOPATH/bin 生成一个可执行的二进制文件。

    JetBrains GoLand建立helloworld

    安装JetBrains GoLand,过程略
    配置goland
    文件(file)->配置(settings)->go

    1. 设置goroot,这个是go的安装目录
    2. 设置gopath:全局global gopath会自动读取环境变量 ,index entire GOPATH是让项目可以共用全局gopath中的package包,我一般去掉勾选,因为我习惯每个项目单独一个环境,不与其他项目公用。
    3. project gopath,设为新建项目的目录。如果本项不设置,将来编译时无法按照Package编译
    4. build tags,设置编译目标

    新建项目HelloWorld.

    新建项目HelloWorld,位置可以放在gopath的src中。
    项目下新建Hello.go文件,代码同上:

    package main
    import(
     "fmt"
     "time"
    )
    
    func main() {
     fmt.Println("Hello world!")
     duration := time.Duration(10)*time.Second
     time.Sleep(duration)
    }
    

    运行(run)菜单->运行->编辑配置
    左上+号,go build
    在这里插入图片描述
    一共有三种配置,每种的设置是不一样的,

    第一种是directroy,即编译目录:

    在这里插入图片描述
    在这里插入图片描述
    按目录编译要求指定目录下要有main包声明和main函数,否则无法编译。

    第二种是编译package

    这种要求在goland中设置project gopath:
    file->settings->Go->GOPATH->PROJECT GOPATH中添加当前项目工程的路径。
    运行,编辑配置,新增go build配置,这里package path要设成helloworld项目名,就是要求软件在本项目中找文件进行编译,输出目录随意,一般设为项目的bin目录
    运行,编译
    在这里插入图片描述
    按package编译不要求有main包声明,可以声明别的包名,也可以不放在main文件中,但要有main函数

    第三种,按文件编译

    在这里插入图片描述
    按文件编译,go文件必须放在包名main文件夹中,指定要编译的文件,此处可以编译多个文件,但必须有一个带main函数
    编译完成,运行即可

    关于 GO MODULE

    GO MODULE不再受GOPATH的限制可以自由编译和包管理。
    (https://goframe.org/prepare/gomodule)
    Golang 的包管理一直被大众所诟病的一个点, 在 1.5 版本之前,所有的依赖包都是存放在 GOPATH 下,没有版本控制。这个类似 Google 使用单一仓库来管理代码的方式。这种方式的最大的弊端就是无法实现包的多版本控制,1.5 版本推出了 vendor 机制。go build 的时候会先去 vendor 目录查找依赖,如果没有找到会再 GOPATH 目录下查找。1.9 版本推出了实验性质的包管理工具 dep,1.11 版本推出 modules 机制,简称 mod。modules 的原型其实是 vgo
    modules 在 Go 1.13 的版本下是默认开启的。

    展开全文
  • ue4 Worldmachine 结合使用

    千次阅读 2017-06-14 18:01:40
    最近项目需求制作一个场景的远景部分。正好可以尝试使用一下UE4的 Landscape。不过直接在 Editor 里刷地形工作量太大,刷出的地形也不真实,最关键的是 Landscape 的工具并...WorldMachine 生成的高度相对人工算...

    最近项目需求制作一个场景的远景部分。正好可以尝试使用一下UE4的 Landscape。不过直接在 Editor 里刷地形工作量太大,刷出的地形也不真实,最关键的是 Landscape 的工具并不是那么好用。

     

    所以我们决定使用 WorldMachine 作为地形的生成工具,将地形的高度图导入 Editor,再在 Editor 中对细节进行修改。WorldMachine 生成的高度图相对人工算出来的要真实,最重要的是快,用它找坡度,沟壑更加准确。

    在 UE4 中使用 WorldMachine 还要解决几个问题。官方有篇 wiki 将的很清楚。World Machine to Unreal Engine 4 - In Depth Guide

    问题1:高度图尺寸

    UE4 的高度图有一些限制,这与 UE4 地形系统的组织有关。高度图中每一个像素对应着地形系统的一个顶点。UE4 的地形组织分为3层:组件 component,分段 section,四边形 quadsLandscape Technical Guide

    四边形是地形系统最小单位,每个四边形对应4个顶点。

    分段由四边形组成,是 drawcall 和 LOD 的最小单位。因为要对每个分段单独做 LOD,高度图需要做 mipmap,所以每个分段的高度图都是2的整数次幂,可以是 8x8 到 256x256 中间的一个。分段中每个四边形共享顶点,所以每边四边形的个数是 x-1。

    组件由分段组成,每个组件只能有 1x1 个或者 2x2 个分段。组件是渲染、可视性和碰撞的基本单元。每一边组件的数量可以是1到32中的一个,长和宽可以不相同。组件越多,CPU 消耗越大。

    了解了以上的关系,高度图的尺寸就可以计算出来了。但是这里推荐的方法是在 Editor 里调整组件和分段的选项,来得到高度图的尺寸。

    高度图尺寸

    上图中的高度尺寸就是 505x505。

    问题2:世界尺寸

    第二个问题就是要弄清地形系统中的距离表示的实际世界尺寸。正常地形系统中顶点之间距离是1ued,代表实际中的1cm,但是在创建时可以看到 Scale 是 (100, 100, 100)。所以顶点间距离是1m。地形系统的高度范围是 -255 到 257,同样在 Scale = 100 时,单位是 m。如果希望上图中的设置,高度图1像素对应1m,那么 WorldMachine 的设置是,分辨率 505x505,宽是505m,高是505m。海拔的设置,由于world machine从0开始,所以要设成512m。

    分辨率,宽,高

    高度

    之后的操作就是在 WorldMachine 里做图并导入 Editor。WorldMachine 默认都是 km 级别的,可以放大 100 倍,方便在 WorldMachine 里操作。

    问题3:地形材质

    地形材质方面主要要搞清 LayerInfo 的2两种混合模式和材质中的3种混合类型的含义。

    LayerInfo 的2两种混合模式:Weight-Blend(normal), No Weight-Blend

    Weight-Blend(normal), No Weight-Blend

    Weight-Blend 的层权重和为1,增加一个层的权重,其他层的权重就会减少。No Weight-Blend 的层单独计算权重,不对其他层有影响。

    No Weight-Blend 的层单独计算权重

    图中,红色和蓝色部分为 Weight-Blend,绿色部分为 No Weight-Blend。先刷红色,再刷蓝色,绿色。蓝色部分覆盖红色部分的区域,红色部分的权重变成了0。而绿色部分覆盖的区域红色部分权重没有变。

    LB_WeightBlend,LB_AlphaBland,LB_HeightBland

    WeightBlend 和 HeightBland 都是权重混合。在同一像素上不同层的权重和为1。但是 HeightBland 提供高度图。在边界产生下图效果。

    HeightBland

    WeightBlend 和 HeightBland 都是无序的, 减少一个层的权重,其他层的权重会增加,但是增加那个并不确定。

    AlphaBland 是有序的,好像一层覆盖一层,减少一层会露出下一层。这里官方文档说的也不详细。查了一下代码
    int32 UMaterialExpressionLandscapeLayerBlend::Compile(class FMaterialCompiler* Compiler, int32 OutputIndex, int32 MultiplexIndex)

    他们的关系应该是这样的。

    blend 公式

    w是权重,color 是这个点的颜色, AlphaBland 在最后才混合,每个 Alpha 层都会 lerp 一次,顺序不定。


     

    原文链接:http://www.jianshu.com/p/f0feccb546f2
     

     

    欢迎大家来我的新家看一看 3wwang个人博客-记录走过的技术之路

    展开全文
  • 以hello world为例,详细分析程序的运行过程 (一)环境说明: IDE :Visual Studio 2017 语言:C++ 示例代码: #include<iostream> using namespace std; void main() { cout << “Hello World”; } 在...
  • hello world是怎样运行的?

    千次阅读 2019-06-15 08:46:03
    hello, world程序以字节方式存放于文件中,如下所示。其每个字符对应一个数字,具体可参考ASCII 码表。 1 Hello world 程序的 ASCII 码表示 2.将程序翻译成机器可读的格式 因为我们输入的hello...
  • 参见 :http://learnyousomeerlang.com/buckets-of-sockets为了加深理解,自译如下,若理解有误或更好的建议,请帮忙指出, :)Buckets of Sockets目前为止,我们了一些关于Erlang本身很有趣的事,但是却极少与...
  • GO - HelloWorld

    千次阅读 2013-01-28 23:33:18
    本节将通过Hello World带领大家进入Go的世界,并由此介绍Go代码的主要结构、部分关键字和包的一些特性。为阅读后面的打下基础。 1. Let's go     咱们以往学习任何程序都会以Hello World作为第一个实例,...
  • 计算机程序是怎样运行的-hello world程序运行原理

    千次阅读 多人点赞 2018-01-27 00:34:16
    hello, world程序以字节方式存放于文件中,如下所示。其每个字符对应一个数字,具体可参考ASCII 码表。 1 Hello world 程序的 ASCII 码表示 2.将程序翻译成机器可读的格式 因为我们...
  • World Mobile Q1季度报告

    2022-04-06 19:10:22
    1.0 2022年,一个忙碌开始 2.0 合作伙伴:WMT上线kucoin、ZB、AstroSwap、Minswap(WMT共上线9个CEX...World Mobile成为了GSMA的成员,致力于建立更好的电信公司的全球组织。 3.0 登陆新闻头条: Wor...
  • //第一讲 Hello World程序 #include int main() { printf("Hello World!"); return 0; } 这个程序(以上6行代码)的功能非常简单,就是在屏幕上输出(也称为打印出)这么几个字: Hello World! 想象你是一个包工头,承包了...
  • hello world解析执行过程

    千次阅读 2015-12-25 16:41:11
    学习任何一门编程语言,都会从hello world 开始。对于一门从未接触过的语言,在短时间内我们都能用这种语言写出它的hello world。 然而,对于hello world 这个简单程序的内部运行机制,我相信还有很多人都不是很...
  • 一、用 Maven 写一个 HelloWorld 我们使用 Maven 来创建一个项目,感受一下 Maven 如何使用。 先随便找个盘,然后创建一个项目名字。我这里项目名字就用 helloworld 了。(这里注意一下,项目名字要用小写,不要有...
  • 【Mybatis】Helloworld

    千次阅读 2017-11-03 16:40:45
    你首先需要两个jar,一个是连接Mysql必须的jar,这里以Mysql例子,Orcale等数据库则换成相应的jar包即可,可以到Mysql的官网下载: https://dev.mysql.com/downloads/connector/j/ ,下载之后取走其中的mysql-...
  • 老规矩 从HelloWorld 开始吧

    千次阅读 2018-07-02 17:51:08
    java零基础入门-核心语法...令人兴奋的 hello world !!!3.java的编译过程4.开发工具选择5.Eclipse如何使用JDK JRE 是什么?JRE: Java Runtime Environment 翻译:java 运行 环境JDK:Java Development Kit 翻...
  • 前言 在IOS开发之路的博文第一章:(IOS开发入门介绍http://blog.csdn.net/csdn_aiyang)我大致...这一篇我将手把手教大家完成第一个IOS项目——”Hello World“。 新建项目 1、打开Xcode,点击 Create a new Xcode ...
  • Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训初学者理解Spring中的依赖注入的基本概念. 先介绍依赖注入的基本概念,然后以构造器注入为例实现了...
  • 准备写一个论文学习专栏...平时只是阅读论文,有很多知识意识不到,当你真正去着手写的时候,发现写完之后可能只有自己明白了个啥。包括从组织、结构、描述上等等很多方面都具有很多问题。另一个是对于专业术语、...
  • 但是在这个World-Wide-Web出现之后,中的很多词语都耳熟能详了吧,比如Yahoo、Google和Facebook,这都是互联网发展历史上里程碑式的伟大企业。 在TCP/IP协议上传输信息的方式很早就出现了,比如FTP就是通过TCP/IP...
  • cocos2dx的游戏世界:是由Scene组成的,Scene再由一个个Layer层叠表现,然后再有一个Director来导演...UE的游戏世界:是由关卡(Level)组成的,由一个或多个Level组成一个World。 一个游戏引擎的“世界观”关系到了...
  • er转换成关系模型 关系 (Relations) Relations specify that how a entity of a entity set is related to the entity of other set. 关系指定一个实体集的实体如何与另一个集的实体相关。 关系类型 (Types of ...
  • 论文阅读:DuEE:A Large-Scale Dataset for Chinese Event Extraction in Real-World Scenarios 基于现实场景的大规模中文事件抽取数据集 目录论文阅读:DuEE:A Large-Scale Dataset for Chinese Event Extraction ...
  • --项目组织,包名,版本,包类型,--> <groupId>com.javainuse</groupId> <artifactId>boot-drools <version>1.0.0-SNAPSHOT <packaging>jar <!--项目名字,项目描述--> <name>boot-drools <description>Demo ...
  • 如果我们需要编译一个运行在X86架构上的helloworld程序,只需要在linux系统下执行 gcc helloworld.c -o helloworld 如果要在X86主机上编译一个在ARM系统上运行的程序,就需要用到交叉编译器。 1. 编译器命名规则: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 49,414
精华内容 19,765
关键字:

world做组织关系图