使用cmake生成.so动态库

CMakeLists.txt内容如下:

#cmake for GLTranslation
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/out)

aux_source_directory(module/GLTranslation GLTRANSLAYION_SOURCE_FILES)

add_library(GLTranslation SHARED ${GLTRANSLAYION_SOURCE_FILES})

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/out)指定了生成.so的路径

add_library 使用指定的源文件向工程中添加一个库。

add_library( [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 … sourceN)
  添加一个名为的库文件,该库文件将会根据调用的命令里列出的源文件来创建。对应于逻辑目标名称,而且在一个工程的全局域内必须是唯一的。待构建的库文件的实际文件名根据对应平台的命名约定来构造(比如lib.a或者.lib)。指定STATIC,SHARED,或者MODULE参数用来指定要创建的库的类型。STATIC库是目标文件的归档文件,在链接其它目标的时候使用。SHARED库会被动态链接,在运行时被加载。MODULE库是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接。如果没有类型被显式指定,这个选项将会根据变量BUILD_SHARED_LIBS的当前值是否为真决定是STATIC还是SHARED。

使用下述格式,add_library命令也可以用来创建导入的库目标:

add_library( <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED)
  导入的库目标是引用了在工程外的一个库文件的目标。没有生成构建这个库的规则。这个目标名字的作用域在它被创建的路径及以下有效。他可以向任何在该工程内构建的目标一样被引用。导入库为类似于target_link_libraries命令中引用它提供了便利。关于导入库细节可以通过指定那些以IMPORTED_的属性设置来指定。其中最重要的属性是IMPORTED_LOCATION(以及它的具体配置版本,IMPORTED_LOCATION_),它指定了主库文件在磁盘上的位置。查阅IMPORTED_*属性的文档获取更多的信息。

下面是实例,把OpenGL绘图的程序打包成libGLTranslation.so动态库

头文件GLTranslation.h

//
// Created by czh on 1/18/19.
//

#ifndef GLTRANSLATION_H
#define GLTRANSLATION_H

#include "iostream"
#include <glad/glad.h>
#include <string>

void GLinit(int width, int height);

void GLTextureUpdate(uint width, uint height, int channel, unsigned char *data);

void GLdrawRender();

void GLFree();

#endif //GLTRANSLATION_H

源文件GLTranslation.cpp

//
// Created by czh on 2/1/19.
//
#include "GLTranslation.h"

void GLinit(int width, int height);

void GLTextureUpdate(uint width, uint height, int channel, unsigned char *data);

void GLdrawRender();

void GLFree();

GLuint shaderID;
GLuint textureID;
GLuint VAO;
GLuint VBO;

std::string defaultVshader2D =
        "#version 300 es                                    \n"
        "layout (location = 0) in vec4 vertex;              \n"
        "out vec2 TexCoords;                                \n"
        "void main()                                        \n"
        "{                                                  \n"
        "   TexCoords = vertex.zw;                          \n"
        "   gl_Position = vec4(vertex.xy, 0.0, 1.0);        \n"
        "}                                                  \n";

std::string defaultFshader2D =
        "#version 300 es                                    \n"
        "precision mediump float;                           \n"
        "in vec2 TexCoords;                                 \n"
        "out vec4 color;                                    \n"
        "uniform sampler2D image;                           \n"
        "void main()                                        \n"
        "{                                                  \n"
        "   color = texture(image, TexCoords);              \n"
        "}                                                  \n";

GLfloat defaultVertices2D[16] = {
        // Pos      // Tex
        -1.0f, -1.0f, 0.0f, 1.0f,
        1.0f, -1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, 0.0f, 0.0f,
        1.0f, 1.0f, 1.0f, 0.0f
};

GLuint defaultIndices2D[6] = {
        2, 0, 1,
        2, 3, 1
};

void GLStatusInit(int width, int height) {
    glViewport(0, 0, width, height);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}

void GLcheckCompileErrors(uint object, std::string type) {
    GLint success;
    GLchar infoLog[1024];
    if (type != "PROGRAM") {
        glGetShaderiv(object, GL_COMPILE_STATUS, &success);
        if (!success) {
            glGetShaderInfoLog(object, 1024, NULL, infoLog);
            std::cout << "#Err! SHADER: CompileErrors: Type: " << type << "\n"
                      << infoLog << std::endl;
        }
    } else {
        glGetProgramiv(object, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(object, 1024, NULL, infoLog);
            std::cout << "#Err! Shader: CompileErrors: Type: " << type << "\n"
                      << infoLog << std::endl;
        }
    }
}

void GLShaderInit() {
    GLuint sVertex, sFragment;

    const char *vchar = defaultVshader2D.data();
    const char *fchar = defaultFshader2D.data();

    sVertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(sVertex, 1, &vchar, nullptr);
    glCompileShader(sVertex);
    GLcheckCompileErrors(sVertex, "VERTEX");

    sFragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(sFragment, 1, &fchar, NULL);
    glCompileShader(sFragment);
    GLcheckCompileErrors(sFragment, "FRAGMENT");

    shaderID = glCreateProgram();
    std::cout << "#glCreateProgram ID:" << shaderID << std::endl;

    glAttachShader(shaderID, sVertex);
    glAttachShader(shaderID, sFragment);
    glLinkProgram(shaderID);
    GLcheckCompileErrors(shaderID, "PROGRAM");

    glDeleteShader(sVertex);
    glDeleteShader(sFragment);
}

void GLTextureInit() {
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

#define GL_BGRA_IMG                       0x80E1

void GLTextureUpdate(uint width, uint height, int channel, unsigned char *data) {
    if (channel == 4) {
        glBindTexture(GL_TEXTURE_2D, textureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_IMG, GL_UNSIGNED_BYTE, data);
        //glTexDirectVIV(GL_TEXTURE_2D, width, height, GL_RGBA, (GLvoid **)(&data));
    } else {
        glBindTexture(GL_TEXTURE_2D, textureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    }
}

void GLRenderInit() {
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(defaultVertices2D), defaultVertices2D, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *) (0 * sizeof(float)));
    glEnableVertexAttribArray(0);
}

void GLdrawRender() {
    glUseProgram(shaderID);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureID);

    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, defaultIndices2D);
    glBindVertexArray(0);
};

void GLinit(int width, int height) {
    GLStatusInit(width, height);
    GLShaderInit();
    GLTextureInit();
    GLRenderInit();
}

void GLFree() {
    //free shader
    glDeleteProgram(shaderID);
    //free texture
    glBindTexture(GL_TEXTURE_2D, 0);
    glDeleteTextures(1, &textureID);
    //free render
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDeleteBuffers(1, &VAO);
    glDeleteBuffers(1, &VBO);
}

编译,然后在工程目录的build/out路径下找到生成的GLTranslation.so
需要用的时候加上头文件GLTranslation.h
查看链接的依赖项

 readelf -d build/out/libGLTranslation.so 

结果如下:

Dynamic section at offset 0x3c88 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libGLTranslation.so]
 0x000000000000000c (INIT)               0x1a28
 0x000000000000000d (FINI)               0x2614
 0x0000000000000019 (INIT_ARRAY)         0x203c68
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x203c78
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x1f0
 0x0000000000000005 (STRTAB)             0xa60
 0x0000000000000006 (SYMTAB)             0x2b0
 0x000000000000000a (STRSZ)              1877 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x204000
 0x0000000000000002 (PLTRELSZ)           504 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x1830
 0x0000000000000007 (RELA)               0x1320
 0x0000000000000008 (RELASZ)             1296 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x1260
 0x000000006fffffff (VERNEEDNUM)         3
 0x000000006ffffff0 (VERSYM)             0x11b6
 0x000000006ffffff9 (RELACOUNT)          4
 0x0000000000000000 (NULL)               0x0

可以看出依赖的库文件
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值