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

工程内分子目录存放源代码的处理(linux cmake)_第1张图片

1.子目录的CMakeLists文件

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

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

#这是子目录的CMakefile, 编译过程中的提示信息
message(STATUS "Enter mqtt dir...")

#要点1:这个MODULE_MQTT需要在源代码根目录被引用
set(MODULE_MQTT gpMqtt)

#要点2:通过这个set语句。${MODULE_MQTT}这个模块才会被上层应用访问到
set(MODULE_MQTT ${MODULE_MQTT} PARENT_SCOPE)

#这个是普通做法,指示当前目录下的所有源代码参与编译add_library.无需逐个文件手工指定
aux_source_directory (. SOURCES_MQTT)

#要点3:子目录在要点1被定义为一个子模块,为了参与主目录的工程的编译,它需要被编译为一个动态库或者静态库:动态库:SHARED|静态库:STATIC
add_library(${MODULE_MQTT} STATIC ${SOURCES_MQTT})

#这里是方便这个模块访问其它目录下的头文件。
include_directories (${PROJECT_SOURCE_DIR}/../include)
include_directories (${PROJECT_SOURCE_DIR}/../calc)
include_directories (${PROJECT_SOURCE_DIR}/../common)
include_directories (${PROJECT_SOURCE_DIR}/../sensor)
include_directories (${PROJECT_SOURCE_DIR}/../include)
include_directories (${PROJECT_SOURCE_DIR}/../mqtt)
include_directories (${PROJECT_SOURCE_DIR})

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

#这是正常的编译目标,假定输出的二进制可执行文件叫my_app
add_executable (my_app ${SOURCES})

#注意这里添加的对子目录library的依赖
target_link_libraries(my_app ${MODULE_MQTT})

3.结语:

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

附录1:FAQ:

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

//gptimestr(),这个函数用来返回一个时间字符串,它的定义如下:
const char *gptimestr(void) {

    time_t rawtime;
    struct tm *timeinfo;

    // 获取当前时间
    time(&rawtime);
    timeinfo = localtime(&rawtime);

    // 获取年、月、日、小时、分钟、秒
    int year = timeinfo->tm_year + 1900;
    int month = timeinfo->tm_mon + 1;
    int day = timeinfo->tm_mday;
    int hour = timeinfo->tm_hour;
    int minute = timeinfo->tm_min;
    int second = timeinfo->tm_sec;

    static char dumb[128];
    // 打印结果
    sprintf(dumb, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);

    return dumb;
}

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

解决方案有两点:

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

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

你可能感兴趣的:(Linux,C,linux,前端,运维)