I'm leanrning yocto and bitbake and I'm confused with fews things.
When I'm developing a C project my tree files look like :
myproject
├── commons
│ ├── commons.c
│ ├── commons.h
│ └── path.h
├── config
│ ├── config.c
│ └── config.h
├── errors
│ ├── error.c
│ └── error.h
├── files
│ ├── COPYING
│ ├── ...
├── jimini
│ ├── jimini.c # source including the main()
│ └── jimini.h
├── Doxyfile
├── CMakeLists.txt
└── jimini-collector_0.3.bb
My CMakeLists.txt look like :
cmake_minimum_required(VERSION 3.0.0)
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
project(myproject VERSION 0.3.0)
find_library(LIBCONFIG config)
message(STATUS "libconfig path : ${LIBCONFIG}")
find_library(CURL curl)
message("CURL path : ${CURL}")
find_library(JSON json-c)
message("JSON path : ${JSON}")
find_library(RT rt)
message("RT path : ${RT}")
include(CTest)
enable_testing()
aux_source_directory(../commons SOURCES)
aux_source_directory(../config SOURCES)
aux_source_directory(../errors SOURCES)
aux_source_directory(../jimini SOURCES)
message(STATUS "project folder : " ${CMAKE_CURRENT_SOURCE_DIR})
message(STATUS "My sources: " ${SOURCES})
add_executable(${PROJECT_NAME} ${SOURCES})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
set(CMAKE_BUILD_TYPE Debug)
#set(CMAKE_BUILD_TYPE RelWithDebInfo)
target_link_libraries(${PROJECT_NAME} config)
target_link_libraries(${PROJECT_NAME} m)
target_link_libraries(${PROJECT_NAME} pthread)
target_link_libraries(${PROJECT_NAME} curl)
target_link_libraries(${PROJECT_NAME} json-c)
target_link_libraries(${PROJECT_NAME} rt)
# install the executable in /usr/bin
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
My recipe look like :
DESCRIPTION="This is my recipe to my super package"
MAINTAINER="Me <me#me.com>"
# Define license file and file checksum verification
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=39bba7d2cf0ba1036f2a6e2be52fe3f0"
DEPENDS += "libconfig"
DEPENDS += "json-c"
FILESEXTRAPATHS_prepend := "${THISDIR}"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
FILESEXTRAPATHS_prepend := "${THISDIR}/commons:"
FILESEXTRAPATHS_prepend := "${THISDIR}/config:"
FILESEXTRAPATHS_prepend := "${THISDIR}/errors:"
FILESEXTRAPATHS_prepend := "${THISDIR}/jimini:"
# include license and cmake config files
SRC_URI+="file://COPYING file://CMakeLists.txt"
# include sources files
SRC_URI+= " file://jimini.c file://commons.c file://config.c file://error.c"
SRC_URI+= " file://jimini.h file://commons.h file://path.h file://config.h file://error.h"
# where to copy sources and headers files
S="${WORKDIR}"
# define dependencies to build and package
inherit pkgconfig cmake
I'm not understanding how can I set the recipe to copy the local sources in sub folders. Bitbake copy each sources in the same folder and the code can't be compiled.
I've try to set differently the S="${WORKDIR}" but without result.
Can you give me an explanation ?
Thank you.
EDIT :
I've corrected my files and now it's working.
My CMakeLists.txt, now look like :
cmake_minimum_required(VERSION 3.0.0)
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
project(myproject VERSION 0.3.0)
find_library(LIBCONFIG config)
message(STATUS "libconfig path : ${LIBCONFIG}")
find_library(CURL curl)
message("CURL path : ${CURL}")
find_library(JSON json-c)
message("JSON path : ${JSON}")
find_library(RT rt)
message("RT path : ${RT}")
include(CTest)
enable_testing()
aux_source_directory(commons SOURCES) # removed the ../
aux_source_directory(config SOURCES) # removed the ../
aux_source_directory(errors SOURCES) # removed the ../
aux_source_directory(jimini SOURCES) # removed the ../
message(STATUS "project folder : " ${CMAKE_CURRENT_SOURCE_DIR})
message(STATUS "My sources: " ${SOURCES})
add_executable(${PROJECT_NAME} ${SOURCES})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
set(CMAKE_BUILD_TYPE Debug)
#set(CMAKE_BUILD_TYPE RelWithDebInfo)
target_link_libraries(${PROJECT_NAME} config)
target_link_libraries(${PROJECT_NAME} m)
target_link_libraries(${PROJECT_NAME} pthread)
target_link_libraries(${PROJECT_NAME} curl)
target_link_libraries(${PROJECT_NAME} json-c)
target_link_libraries(${PROJECT_NAME} rt)
# install the executable in /usr/bin
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
My recipe, now look like :
DESCRIPTION="This is my recipe to my super package"
MAINTAINER="Me <me#me.com>"
# Define license file and file checksum verification
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=39bba7d2cf0ba1036f2a6e2be52fe3f0"
DEPENDS += "libconfig"
DEPENDS += "json-c"
SCR_URI+= "file://files/"
SCR_URI+= "file://commons/"
SCR_URI+= "file://config/"
SCR_URI+= "file://errors/"
SCR_URI+= "file://jimini/"
# include license and cmake config files
SRC_URI+="file://COPYING file://CMakeLists.txt"
# include sources files
SRC_URI+= " file://*.c"
SRC_URI+= "file://*.h"
# where to copy sources and headers files
S="${WORKDIR}"
# define dependencies to build and package
inherit pkgconfig cmake
I've also modified my tree files as suggested in the answer.
FILESEXTRAPATHS is only to add paths where to look for files declared in SRC_URI. You should just do the following:
SRC_URI += "file://files/"
SRC_URI += "file://commons/"
SRC_URI += "file://config/"
SRC_URI += "file://errors/"
SRC_URI += "file://jimini/"
# include license and cmake config files
SRC_URI+="file://COPYING file://CMakeLists.txt"
Also, your tree layout should be the following:
myproject
├── jimini-collector-0.3 # or files, or jimini-collector
│ ├──commons
| │ ├── commons.c
| │ ├── commons.h
| │ └── path.h
| ├── config
| │ ├── config.c
| │ └── config.h
| ├── errors
| │ ├── error.c
| │ └── error.h
| ├── files
| │ ├── COPYING
| │ ├── ...
| ├── jimini
| │ ├── jimini.c # source including the main()
| │ └── jimini.h
| ├── Doxyfile
| ├── CMakeLists.txt
└── jimini-collector_0.3.bb
Related
I'm learning to use LVGL and I plan to use CMake to manage the project. But when I tried to compile, I encountered "undefined reference to". Project Tree looks like this:
.
├── build
├── CMakeLists.txt // C1
└── src
├── CMakeLists.txt // C2
├── lv_conf.h
├── lv_demo_conf.h
├── lv_demos
│ ├── CMakeLists.txt // C3
│ └── src
├── lv_drivers
│ ├── CMakeLists.txt // C4
│ ├── display
│ ├── docs
│ ├── gtkdrv
│ ├── indev
│ ├── library.json
│ ├── LICENSE
│ ├── lv_drivers.mk
│ ├── lv_drv_conf_template.h
│ ├── README.md
│ ├── sdl
│ ├── wayland
│ ├── win32drv
│ ├── win_drv.c
│ └── win_drv.h
├── lv_drv_conf.h
├── lvgl
│ ├── CMakeLists.txt // C5
│ └── src
├── main.c
└── mouse_cursor_icon.c
While I try to make, log is as follows, it seems like I do not add INCLUDE dir or some head file.
[ 76%] Linking C static library liblvgl_lib.a
[ 76%] Built target lvgl_lib
Scanning dependencies of target demo
[ 76%] Building C object bin/CMakeFiles/demo.dir/main.c.o
[ 77%] Linking C executable demo
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: CMakeFiles/demo.dir/main.c.o: in function `main':
/home/xjt/F1C100S_LVGL_DEMO_WITH_CMAKE/src/main.c:18: undefined reference to `fbdev_init'
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: /home/xjt/F1C100S_LVGL_DEMO_WITH_CMAKE/src/main.c:36: undefined reference to `evdev_init'
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: /home/xjt/F1C100S_LVGL_DEMO_WITH_CMAKE/src/main.c:54: undefined reference to `lv_demo_widgets'
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: /home/xjt/F1C100S_LVGL_DEMO_WITH_CMAKE/src/main.c:58: undefined reference to `fbdev_flush'
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: /home/xjt/F1C100S_LVGL_DEMO_WITH_CMAKE/src/main.c:58: undefined reference to `evdev_read'
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: /home/xjt/F1C100S_LVGL_DEMO_WITH_CMAKE/src/main.c:58: undefined reference to `mouse_cursor_icon'
/usr/local/arm/arm-linux-musleabi-cross/bin/../lib/gcc/arm-linux-musleabi/11.2.1/../../../../arm-linux-musleabi/bin/ld: lvgl/liblvgl_lib.a(lv_extra.c.o): in function `lv_extra_init':
Here is my CMakeLists.txt, C1:
PROJECT(F1C100S_DEMO_WITH_CMAKE)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
# INCLUDE_DIRECTORIES(./lib/gpiod/include)
# LINK_DIRECTORIES(./lib/gpiod/lib)
SET(CMAKE_C_COMPILER "arm-linux-musleabi-gcc")
SET(CMAKE_EXE_LINKER_FLAGS "-static")
ADD_COMPILE_OPTIONS(-g)
ADD_SUBDIRECTORY(src bin)
C2:
AUX_SOURCE_DIRECTORY(. SRC_LIST)
# SET(
# ${SRC_LIST}
# lv_drivers/indev/evdev.h
# lv_drivers/display/fbdev.h
# lvgl/demos/lv_demos.h
# )
ADD_SUBDIRECTORY(./lvgl)
ADD_SUBDIRECTORY(./lv_drivers)
ADD_SUBDIRECTORY(./lv_demos)
LINK_DIRECTORIES(./lvgl)
INCLUDE_DIRECTORIES(./lvgl)
SET(
LIB_LIST
lvgl_lib
)
SET(
${LIB_LIST}
lv_drv_lib
)
SET(
${LIB_LIST}
lv_demos_lib
)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR/bin})
ADD_EXECUTABLE(demo ${SRC_LIST})
# TARGET_LINK_LIBRARIES(demo gpiod)
TARGET_LINK_LIBRARIES(demo ${LIB_LIST})
C3:
AUX_SOURCE_DIRECTORY(./src/lv_demo_benchmark DIR_LV_DEMOS_SRC)
AUX_SOURCE_DIRECTORY(./src/lv_demo_keypad_encoder DIR_LV_DEMOS_SRC)
AUX_SOURCE_DIRECTORY(./src/lv_demo_music DIR_LV_DEMOS_SRC)
AUX_SOURCE_DIRECTORY(./src/lv_demo_stress DIR_LV_DEMOS_SRC)
AUX_SOURCE_DIRECTORY(./src/lv_demo_widgets DIR_LV_DEMOS_SRC)
ADD_LIBRARY(lv_demos_lib ${DIR_LV_DEMOS_SRC})
C3 and C4 is similar to C2, just AUX_SOURCE_DIRECTORY and ADD_LIBRARY.
Well, I have a stupid looking solution to this problem, which is to add all the .c files to the SRC_LIST:
# in C2
FILE(GLOB_RECURSE SRC_LIST ./*.c)
This seems unusual because when I build with MAKEFILE it doesn't produce so many .o files.
I would like to implement a library that is based on the gobject type system. So every object is a instance of GObjectClass
In the header gwl-registry.h I have:
#define GWL_TYPE_REGISTRY gwl_registry_get_type()
G_DECLARE_DERIVABLE_TYPE(GwlRegistry, gwl_registry, GWL, REGISTRY, GObject)
Which declares the type and the function that obtains a type. This is what I should do according the gobject tutorial: https://developer.gnome.org/gobject/stable/howto-gobject.html If I understand it correctly these macro's should expand to include the instance cast GWL_REGISTRY() and type check macro GWL_IS_REGISTRY(). However both functions rely on the function gwl_registry_get_type().
If I'm not mistaken this should be implemented in the source file gwl-registry.c. Here I define the type using this code:
G_DEFINE_TYPE_WITH_PRIVATE(GwlRegistry, gwl_registry, G_TYPE_OBJECT)
Than this macro should expand to create the GType gwl_registry_get_type().
Using meson I create a library which currently looks like this:
├── data
│ └── xdg-shell.xml
├── include
│ ├── gwl-display.h
│ ├── gwl.h
│ ├── gwl-import.h
│ ├── gwl-registry.h
│ ├── gwl-registry-private.h
│ └── meson.build
├── meson.build
├── src
│ ├── gwayland.c
│ ├── gwl-display.c
│ ├── gwl-registry.c
│ └── meson.build
└── test
├── display-test.c
├── gwayland-test.c
├── meson.build
├── registry-test.c
└── tests.h
The toplevel meson.build looks like:
project(
'GWayland', 'c',
version : '0.1',
default_options : ['warning_level=3']
)
glib_dep = dependency('glib-2.0')
gobject_dep = dependency('gobject-2.0')
wayland_dep = dependency('wayland-client')
# These arguments are only used to build the shared library
# not the executables that use the library.
lib_args = ['-DBUILDING_GWL']
subdir('src')
subdir('include')
# Make this library usable as a Meson subproject.
gwayland_dep = declare_dependency(
include_directories: include_directories('./include'),
dependencies: [glib_dep, gobject_dep, wayland_dep],
link_with : gwayland_shared_lib
)
subdir('test')
pkg_mod = import('pkgconfig')
pkg_mod.generate(
name : 'GWayland',
filebase : 'gwayland',
description : 'Meson sample project.',
subdirs : 'gwayland',
libraries : gwayland_shared_lib,
version : '0.1',
)
The src meson.build looks like:
gwayland_srcs = [
'gwl-display.c',
'gwl-registry.c',
]
gwayland_shared_lib = shared_library(
'gwayland',
gwayland_srcs,
install : true,
c_args : lib_args,
gnu_symbol_visibility : 'hidden',
include_directories : '../include',
dependencies : [glib_dep, gobject_dep, wayland_dep],
)
and the test:
test_sources = [
'gwayland-test.c',
'tests.h',
'display-test.c',
'registry-test.c',
]
test_deps = [glib_dep, wayland_dep]
test_exe = executable(
'gwayland_test',
test_sources,
dependencies: gwayland_dep,
# link_with : gwayland_shared_lib
env : [
'G_TEST_SRCDIR=#0#'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=#0#'.format(meson.current_source_dir())
]
)
test('gwayland', test_exe)
Currently in the tests I'm calling the casting macro GWL_IS_REGISTRY()
g_assert_true(GWL_IS_REGISTRY(registry));
This leads to the following error:
cc -o test/gwayland_test test/gwayland_test.p/gwayland-test.c.o test/gwayland_test.p/display-test.c.o test/gwayland_test.p/registry-test.c.o -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group src/libgwayland.so /usr/lib/x86_64-linux-gnu/libglib-2.0.so /usr/lib/x86_64-linux-gnu/libgobject-2.0.so /usr/lib/x86_64-linux-gnu/libwayland-client.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/../src' -Wl,-rpath-link,/home/duijn119/github/gwayland/build/src
test/gwayland_test.p/registry-test.c.o: In function `GWL_IS_REGISTRY':
/home/duijn119/github/gwayland/build/../include/gwl-registry.h:30: undefined reference to `gwl_registry_get_type'
collect2: error: ld returned 1 exit status
If I check the library with nm:
nm src/libgwayland.so | egrep 'get_type|new.'
000000000000193f t gwl_display_get_type
0000000000001fcd T gwl_display_new_address
000000000000231f t gwl_registry_get_type
it seems that somehow the gwl_registry_get_type is not exported for use outside of the library, itside the library/compilation unit I can call the function just fine.
Would any one please help me with glib/gobject to tell me what I'm doing wrong, or do I have some issues with meson to build the library and the tests.
You’ve explicitly asked for symbols to not be exported from your library by default:
gnu_symbol_visibility : 'hidden'
Either change that default, or explicitly mark the symbols you want to be exported by using G_MODULE_EXPORT.
You can explicitly mark the gwl_display_get_type() symbol to be exported using
#define GWL_TYPE_REGISTRY gwl_registry_get_type()
G_MODULE_EXPORT
G_DECLARE_DERIVABLE_TYPE(GwlRegistry, gwl_registry, GWL, REGISTRY, GObject)
as the get_type() function is guaranteed to be the first thing emitted by the G_DECLARE_DERIVABLE_TYPE macro.
Currently I have the following project structure, where the libs directory purpose is to store external C libraries that I download from github because they are not available on my OS's repos:
├── cli
│ └── cli.c
├── libs
│ ├── meson.build
│ └── pqueue
│ ├── pqueue.c
│ └── pqueue.h
├── modules
│ ├── algorithms
│ │ ├── a_star.c
│ │ └── a_star.h
│ ├── meson.build
├── meson.build
Where libs/meson.build is:
libpqueue_sources = [
'pqueue/pqueue.c',
]
pqueue_lib = shared_library('pqueue', libpqueue_sources)
pqueue_dep = declare_dependency(link_with: pqueue_lib)
modules/meson.build is:
algs_sources = [
'algorithms/a_star.c',
]
algs_lib = static_library('algorithms',
sources: algs_sources,
include_directories: libs_include_dirs,
dependencies: pqueue_dep)
and meson.build is:
project('graph-search', 'c')
graph_search_include_dirs = include_directories('modules')
libs_include_dirs = include_directories('libs')
subdir('libs')
subdir('modules')
cli_sources = [
'cli/cli.c'
]
executable('cli',
sources: cli_sources,
include_directories : graph_search_include_dirs,
link_with: [algs_lib])
My problem arises when I try to make an #include "pqueue/pqueue.h" inside a_star.h, it says /modules/algorithms/a_star.h:5:10: fatal error: pqueue/pqueue.h: No such file or directory, but when I move the include to a_star.c the error disappears. Sadly I need to include it on the header file because I need to export a struct that uses a type of pqueue.h
Is there a way to include pqueue.h inside a_star.h without using paths like ../../libs/pqueue/pqueue.h?
Because you don't specify libs_include_dirs for cli.c to build, compiler don't know how to search pqueue/pqueue.h.
Change your meson.build to include libs_include_dirs.
diff --git a/meson.build b/meson.build
index 4087a00..3347466 100644
--- a/meson.build
+++ b/meson.build
## -8,5 +8,5 ## cli_sources = [
]
executable('cli',
sources: cli_sources,
- include_directories : graph_search_include_dirs,
+ include_directories : [graph_search_include_dirs, libs_include_dirs],
link_with: [algs_lib])
I'm having issues with cmake while trying to cross compile an existing, large codebase. Our current build system uses a proprietary IDE that is causing a large number of issues -- so we're trying to move away.
I've distilled this to the simplest example I can.
Note: This all works when I don't use the toolchain option with cmake. I can get this to compile and run if just using the native toolchain.
I don't currently suspect issues with the toolchain file for cmake. I have used it to get OpenCV to compile -- with some hacking OpenCV.
The error that I get when trying to cross compile is:
-- The C compiler identification is GNU 4.8.3
-- The CXX compiler identification is GNU 4.8.3
-- Check for working C compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-gcc
-- Check for working C compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-g++
-- Check for working CXX compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/MY_USER/Desktop/test_app/build-test_app
Scanning dependencies of target liba
[ 25%] Building C object libs/liba/CMakeFiles/liba.dir/liba.c.o
Linking C shared library libliba.so
[ 25%] Built target liba
Scanning dependencies of target libb
[ 50%] Building C object libs/libb/CMakeFiles/libb.dir/libb.c.o
make[2]: *** No rule to make target `libs/liba/liba.a', needed by `libs/libb/liblibb.so.1.0.0'. Stop.
make[1]: *** [libs/libb/CMakeFiles/libb.dir/all] Error 2
make: *** [all] Error 2
It's like it's looking for a static version of the library, but I've configured it to use shared objects when calling cmake:
cmake -DBUILD_SHARED_LIBS=1 ..
I've included all of the files in the test project below. This is the same issue I run into when trying to get the larger project to compile.
Project structure:
test_app
├── app
│ ├── appa
│ │ ├── appa.c
│ │ └── CMakeLists.txt
│ └── CMakeLists.txt
├── CMakeLists.txt
├── include
│ ├── liba
│ │ └── liba.h
│ ├── libb
│ │ └── libb.h
│ └── libc
│ └── libc.h
└── libs
├── CMakeLists.txt
├── liba
│ ├── CMakeLists.txt
│ └── liba.c
├── libb
│ ├── CMakeLists.txt
│ └── libb.c
└── libc
├── CMakeLists.txt
└── libc.c
Top level CMakeLists.txt
project(test)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_INSTALL_PREFIX "/opt/test")
set(INSTALL_PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_EXECUTE)
set(TEST_VERSION 1.0.0)
set(TEST_MAJOR_VERSION 1)
set(TEST_GLOBAL_INCLUDES
$<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
set(TEST_GLOBAL_LIB_PATHS
$<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
add_subdirectory(libs)
add_subdirectory(app)
app/CMakeLists.txt
add_subdirectory(appa)
app/appa/CMakeLists.txt
project(appa)
add_executable(appa appa.c)
target_include_directories(appa PUBLIC ${TEST_GLOBAL_INCLUDES})
target_link_libraries(appa libc)
# Set version information
set_target_properties(appa PROPERTIES
VERSION ${TEST_VERSION}
)
# set install destination and permissions
install(
TARGETS appa
RUNTIME DESTINATION lib
PERMISSIONS ${INSTALL_PERMISSIONS}
)
app/appa/appa.c
#include <stdlib.h>
#include <stdio.h>
#include <libc/libc.h>
int main(int argc, char **argv)
{
printf("Hello world: %d\n", libc_function(2));
return EXIT_SUCCESS;
}
include/liba/liba.h
#pragma once
int liba_function(int a);
include/libb/libb.h
#pragma once
int libb_function(int a);
include/libc/libc.h
#pragma once
int libc_function(int a);
libs/CMakeLists.txt
add_subdirectory(liba)
add_subdirectory(libb)
add_subdirectory(libc)
libs/liba/CMakeLists.txt
project(libliba)
add_library(liba liba.c)
target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})
# Set version information
set_target_properties(liba PROPERTIES
VERSION ${TEST_VERSION}
SOVERSION ${TEST_MAJOR_VERSION}
)
# set install destination and permissions
install(
TARGETS liba
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION lib
PERMISSIONS ${INSTALL_PERMISSIONS}
)
libs/liba/liba.c
#include <liba/liba.h>
int liba_function(int a)
{
return a * a;
}
libs/libb/CMakeLists.txt
project(liblibb)
add_library(libb libb.c)
target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})
# Set version information
set_target_properties(libb PROPERTIES
VERSION ${TEST_VERSION}
SOVERSION ${TEST_MAJOR_VERSION}
)
target_link_libraries(libb liba)
# set install destination and permissions
install(
TARGETS libb
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION lib
PERMISSIONS ${INSTALL_PERMISSIONS}
)
libs/libb/libb.c
#include <liba/liba.h>
#include <libb/libb.h>
int libb_function(int a)
{
return liba_function(a) * liba_function(a);
}
libs/libc/CMakeLists.txt
project(liblibc)
add_library(libc libc.c)
target_include_directories(libc PUBLIC ${TEST_GLOBAL_INCLUDES})
# Set version information
set_target_properties(libc PROPERTIES
VERSION ${TEST_VERSION}
SOVERSION ${TEST_MAJOR_VERSION}
)
target_link_libraries(libc libb)
# set install destination and permissions
install(
TARGETS libc
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION lib
PERMISSIONS ${INSTALL_PERMISSIONS}
)
libs/libc/libc.c
#include <libb/libb.h>
#include <libc/libc.h>
int libc_function(int a)
{
return libb_function(a) * libb_function(a);
}
I installed YCM and syntastic for VIM, normally they work fine, but I have problem when it detect some errors in my code, it shows that can NOT find some head files(which is my project head file).
My directory tree shows below:
TOP
├── debug
│ ├── debug.c
│ ├── debug.h
│ ├── debug.mk
│ └── instrument.c
├── driver
│ ├── driver.c
│ ├── driver_ddi.c
│ ├── driver_ddi.h
│ ├── driver.h
│ └── driver.mk
├── include
│ └── common.h
├── libs
├── Makefile
├── mw
│ ├── manager.c
│ └── mw.mk
└── root
├── main.c
└── root.mk
I copied a .ycm_extra_conf.py to the TOP, meanwhile, I will generated tag and cscope file at TOP as well, therefore each time I open file on TOP, like:
howchen#host:~/Work/c/sample/src
-> gvim ./driver/driver.c
to make sure each time I can add tag and cscope file in VIM. The problem is, if I open driver.c, which contain head files: driver.h, driver_ddi.h, debug.h, common.h, code like below:
#include <stdio.h>
#include <stdlib.h>
#include "math.h"
#include "common.h"
#include "debug.h"
#include "driver_ddi.h"
#include "driver.h"
the syntastic or YCM always show it can NOT find common.h and debug.h, other head files are OK.
My YCM and syntastic config part in vimrc file:
" YCM
" let g:ycm_extra_conf_globlist = ['~/.vim/bundle/YouCompleteMe/cpp/ycm/*','!~/*']
let g:ycm_global_ycm_extra_conf = '~/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py'
" Syntastic
let g:syntastic_c_checkers=['make']
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_check_on_open=1
let g:syntastic_enable_signs=1
let g:syntastic_error_symbol = '✗'
let g:syntastic_warning_symbol = '⚠'
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*gbar
My .ycm_extra_conf.py write flags variable as:
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
'-std=c99',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x', #I don't know if I need remove -x
'c',
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I',
'.',
'-I',
'../driver'
'-I',
'../debug'
'-I',
'../include'
'-I',
'../include'
]
any wrong flags I set?
Moved here from the question.
I found the problem:
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
'-std=c99',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x', #I don't know if I need remove -x
'c',
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I./driver',
'-I./debug',
'-I./include',
]
I missed a comma and path should be ./xxx, also neeeeed '-I/usr/include', and '-I/usr/local/include'.