• 工程内分子目录存放源代码的处理(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静态库的形式。

  • 相关阅读:
    为什么现在连Date类都不建议使用了?
    实践分享:30分钟在电脑端运行小程序
    从头训练RNN语言模型,这样的loss正常吗?
    关于城市旅游的HTML网页设计——中国旅游HTML+CSS+JavaScript 出游旅游主题度假酒店 计划出行网站设计
    C语言 数据的存储
    Java需求文档的写法
    (附源码)php丽江旅游服务网站系统 毕业设计 010149
    [C++] STL_list常用接口的模拟实现
    vue使用代理打包之后404,405问题排查
    我们是如何解决偶发性的 502 错误的
  • 原文地址:https://blog.csdn.net/twicave/article/details/132914547