使⽤cmake⽣成.so动态库
<内容如下:
#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"
#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 = , 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)
cmake如何使用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]
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论