• 工程内分子目录存放源代码的处理(linux cmake)


    1.子目录的CMakeLists文件

    注意其中的三个要点,特别注意那个set ....PARENT_SCOPE

    那条语句才把子目录里定义的对象让上层目录可见。

    1. #这是子目录的CMakefile, 编译过程中的提示信息
    2. message(STATUS "Enter mqtt dir...")
    3. #要点1:这个MODULE_MQTT需要在源代码根目录被引用
    4. set(MODULE_MQTT gpMqtt)
    5. #要点2:通过这个set语句。${MODULE_MQTT}这个模块才会被上层应用访问到
    6. set(MODULE_MQTT ${MODULE_MQTT} PARENT_SCOPE)
    7. #这个是普通做法,指示当前目录下的所有源代码参与编译add_library.无需逐个文件手工指定
    8. aux_source_directory (. SOURCES_MQTT)
    9. #要点3:子目录在要点1被定义为一个子模块,为了参与主目录的工程的编译,它需要被编译为一个动态库或者静态库:动态库:SHARED|静态库:STATIC
    10. add_library(${MODULE_MQTT} STATIC ${SOURCES_MQTT})
    11. #这里是方便这个模块访问其它目录下的头文件。
    12. include_directories (${PROJECT_SOURCE_DIR}/../include)
    13. include_directories (${PROJECT_SOURCE_DIR}/../calc)
    14. include_directories (${PROJECT_SOURCE_DIR}/../common)
    15. include_directories (${PROJECT_SOURCE_DIR}/../sensor)
    16. include_directories (${PROJECT_SOURCE_DIR}/../include)
    17. include_directories (${PROJECT_SOURCE_DIR}/../mqtt)
    18. include_directories (${PROJECT_SOURCE_DIR})

    2.主工程添加对子工程的代码依赖

    1. #这是正常的编译目标,假定输出的二进制可执行文件叫my_app
    2. add_executable (my_app ${SOURCES})
    3. #注意这里添加的对子目录library的依赖
    4. target_link_libraries(my_app ${MODULE_MQTT})

    3.结语:

    1. CMakeLists单目录的语法未给出,这个自行查阅即可。
    2. 这只是其中的一种多目录代码联合编译的方法。存在其他途径,但是这个够用。
    3. 可以参照那个暴露子目录的符号定义给上级目录的语法,直接关联源代码,理论上也是可以的。

    附录1:FAQ:

    要特别谨慎在.so动态库的函数里使用static char[1024].因为.so随时可能从内存中卸载,例如:

    1. //gptimestr(),这个函数用来返回一个时间字符串,它的定义如下:
    2. const char *gptimestr(void) {
    3.     time_t rawtime;
    4.     struct tm *timeinfo;
    5.     // 获取当前时间
    6.     time(&rawtime);
    7.     timeinfo = localtime(&rawtime);
    8.     // 获取年、月、日、小时、分钟、秒
    9.     int year = timeinfo->tm_year + 1900;
    10.     int month = timeinfo->tm_mon + 1;
    11.     int day = timeinfo->tm_mday;
    12.     int hour = timeinfo->tm_hour;
    13.     int minute = timeinfo->tm_min;
    14.     int second = timeinfo->tm_sec;
    15.     static char dumb[128];
    16.     // 打印结果
    17.     sprintf(dumb, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
    18.     return dumb;
    19. }

    上面这个函数直接在主工程里使用没有问题,但是一旦在子工程中编译,就会遇到segment fault.调试时,发现返回的static char dumb[128]已经被废弃。

    解决方案有两点:

    1.在函数中使用静态成员变量避免malloc free在多线程或者类似这种跨.so动态库调用,都会出现问题。

    2.可以针对子模块的输出lib,始终采用static静态库的形式。

  • 相关阅读:
    【华为上机真题 2022】| 差点没过
    Vue响应式状态ref()与reactive()
    Web大学生网页作业成品——游戏主题HTM5网页设计作业成品 (HTML+CSS王者荣耀8页)
    迅为RK3568开发板Debian系统使用python 进行摄像头开发
    【FPGA教程案例60】深度学习案例7——基于FPGA的CNN卷积神经网络之testbench编写以及CNN仿真测试
    [自用]手推DDPM公式
    成为一个优秀的 Python 数据分析师需要哪些知识?
    「网络编程」数据链路层协议_ 以太网协议学习
    Blazor前后端框架Known-V1.2.14
    PyCharm 常用快捷键
  • 原文地址:https://blog.csdn.net/twicave/article/details/132914547