I'm trying to integrate a side program (Program B) into an existing program (Program A) compiled/built with CMake. Currently CMake handles finding all the resources for and compiling Program A. I would like to include a couple .h files that Program B points to, so I can embed some of Program B's .c code in Program A.
I've tried playing around with one of the CMakeLists.txt files and even added some .c files to the add_library() block, but I still receive an "undefined reference to THIS_FUNCTION" error on compile.
Thank you for your time!
EDIT: Here's part of the CMakeList.txt file I updated on the RPi
add_library(rtlsdr_shared SHARED
librtlsdr.c
tuner_e4k.c
tuner_fc0012.c
tuner_fc0013.c
tuner_fc2580.c
tuner_r82xx.c
gpu_fft.c #Added this and a couple other .c files
)
target_link_libraries(rtlsdr_shared
${LIBUSB_LIBRARIES}
)
EDIT 2:
Proj A => rtl-sdr
Proj B => gpu_fft
rtl-sdr/
CMakeLists.txt
build/
cmake/
include/
m4/
src/
CMakeLists.txt
gpu_fft/
makefile
I think you better should build program B as a shared library, and add to the include_directories of program A the includes of program B. Then target_link_libraries to your program A.
Edit:
What I have in mind is a project with this folder structure:
projA/
CMakeLists.txt
include/
src/
B/
CMakeLists.txt
include/
src/
The CMakeLists.txt in B is very classical and build the shared library libB.so (e.g. on linux, .dll on WIN32).
In the CMakeLists.txt of projA folder put:
# first build project B
add_subdirectory(B)
# add include directory of project B
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/B/include")
# [...] build here your project
# and finally:
target_link_libraries(A B)
I hope it helps
EDIT2:
To build shared libraries you can set:
OPTION(BUILD_SHARED_LIBS TRUE)
or simply
SET(BUILD_SHARED_LIBS TRUE)
EDIT 3:
You can also use it simply as an external library. Set libraries search path first:
LINK_DIRECTORIES(${yourPathToLibB})
Don't forget to
include_directories("${yourPathToLibB}/include")
too. And then just do
TARGET_LINK_LIBRARIES(A B)
Related
Hi I have a directory called "Question 1" with the following structure:
.idea
cmake-build-debug
1a.c
1b.c
1c.c
CMakeLists.txt
.idea and cmake-build-debug are folders containing other data which come default when creating a project (I'm using CLion), the other 3 are my source files i.e. 1a.c, 1b.c, 1c.c. My CMakeLists.txt file contains the following:
cmake_minimum_required(VERSION 3.7)
project(CLion)
set(CMAKE_C_STANDARD 99)
set(SOURCE_FILES 1b.c)
add_executable(CLion ${SOURCE_FILES})
As you can imagine per above I can only run the source file 1b.c. How do I edit CMakeLists.txt so that I can build an executable for each source file?
Each add_executable() call in your CMakeLists.txt specifies a separate executable to build. Since you want three executables, you need three such calls.
Furthermore, each executable needs a different name. In the case where each executable is built from its own source file, it is conventional for the names of the sources and executables to be related. In particular, I would expect the executable built from 1b.c to be named 1b.
Putting that together, here's one way to do it:
cmake_minimum_required(VERSION 3.7)
project(CLion)
set(CMAKE_C_STANDARD 99)
add_executable(1a 1a.c)
add_executable(1b 1b.c)
add_executable(1c 1c.c)
Note that you don't need to use a variable to designate the source files for an executable. Moreover, if you want to use variables then there is nothing special about the variable name SOURCE_FILES. For example, you could needlessly complicate the above example by introducing per-target source variables, like so:
cmake_minimum_required(VERSION 3.7)
project(CLion)
set(CMAKE_C_STANDARD 99)
set(SOURCES_1A 1a.c)
set(SOURCES_1B 1b.c)
set(SOURCES_1C 1c.c)
add_executable(1a ${SOURCES_1A})
add_executable(1b ${SOURCES_1B})
add_executable(1c ${SOURCES_1C})
I'm currently using recursive make and autotools and am looking to migrate to CMake for a project that looks something like this:
lx/ (project root)
src/
lx.c (contains main method)
conf.c
util/
str.c
str.h
etc.c
etc.h
server/
server.c
server.h
request.c
request.h
js/
js.c
js.h
interp.c
interp.h
bin/
lx (executable)
How should I go about this?
If there's never any source higher than the lx/src directory, then there's no need for the lx/CMakeLists.txt file. If there is, it should look something like this:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(lx)
add_subdirectory(src)
add_subdirectory(dir1)
add_subdirectory(dir2)
# And possibly other commands dealing with things
# directly in the "lx" directory
...where the subdirectories are added in library dependency order. Libraries that depend on nothing else should be added first, and then libraries that depend on those, and so on.
lx/src/CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(lx_exe)
add_subdirectory(util)
add_subdirectory(js)
add_subdirectory(server)
set(lx_source_files conf.c lx.c)
add_executable(lx ${lx_source_files})
target_link_libraries(lx server)
# also transitively gets the "js" and "util" dependencies
lx/src/util/CMakeLists.txt
set(util_source_files
etc.c
etc.h
str.c
str.h
)
add_library(util ${util_source_files})
lx/src/js/CMakeLists.txt
set(js_source_files
interp.c
interp.h
js.c
js.h
)
add_library(js ${js_source_files})
target_link_libraries(js util)
lx/src/server/CMakeLists.txt
set(server_source_files
request.c
request.h
server.c
server.h
)
add_library(server ${server_source_files})
target_link_libraries(server js)
# also transitively gets the "util" dependency
Then, in a command prompt:
mkdir lx/bin
cd lx/bin
cmake ..
# or "cmake ../src" if the top level
# CMakeLists.txt is in lx/src
make
By default, the lx executable will end up in the "lx/bin/src" directory using this exact layout. You can control what directory it ends up in by using the RUNTIME_OUTPUT_DIRECTORY target property and the set_property command.
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:RUNTIME_OUTPUT_DIRECTORY
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_property
Refer to target_link_libraries libs either by CMake target name, if the lib is built as a CMake target via add_library, or by full path to the library file otherwise.
See also, the output of "cmake --help-command target_link_libraries", or any other cmake command, and the full online documentation for cmake commands found here:
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Commands
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries
Steinberg VST3 library has a reusable method which recursively loops through subdirectories and adds them if they include a CMakeLists.txt file:
# add every sub directory of the current source dir if it contains a CMakeLists.txt
function(smtg_add_subdirectories)
file(GLOB subDirectories RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
foreach(dir ${subDirectories})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/CMakeLists.txt")
add_subdirectory(${dir})
endif()
endif()
endforeach(dir)
endfunction()
https://github.com/steinbergmedia/vst3_cmake/blob/master/modules/SMTG_AddSubDirectories.cmake
I have a cmake project wherein I build .c & .h files from .lcm files (see e.g., Lightweight Communications Marshalling (please google for this, my reputation points only allow 2 links :)). The folder structure is as follows -
root
CMakeLists.txt
lcmtypes
example_msg.lcm
src/test_lib
CMakeLists.txt
test_lib.c, test_lib.h
src/listener.c
src/send_message.c
Some notes:
example_msg.lcm generates example_msg.h / example_msg.c which are compiled as a static library, say libexample_msg.a They are also copied to a new folder build/include/lcmtypes.
listener.c & send_message.c compile as stand-alone executables using libexample_msg.a
test_lib compiles as a static library libtest_lib.a, independent of libexample_msg.a and copies test_lib.h to build/include/test_lib.
However,
if I change something in test_lib.h, cmake recompiles libexample_msg.a all over again;
on the other hand, if I change something in listener.c, cmake does not compile libexample_msg.a (which is expected, since nothing in example_msg.lcm changed);
if I do not install test_lib.h header, and change something in test_lib.h, libexample_msg.a does not recompile.
Is this behavior expected? I don't think it is. Is there something I am missing in the cmake process? How do I prevent libexample_msg.a from being compiled if test_lib changes?
root.CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.0)
lcmtypes_build()
add_executable(send_message src/send_message.c)
pods_use_pkg_config_packages(send_message lcm lcmtypes_p1)
add_executable(listener src/listener.c)
pods_use_pkg_config_packages(listener lcm lcmtypes_p1)
pods_install_executables(send_message listener)
add_subdirectory(src/test_lib)
test_lib/CMakeLists.txt
add_library(test_lib test_lib.c)
pods_use_pkg_config_packages(test_lib lcm lcmtypes_p1)
pods_install_libraries(test_lib)
pods_install_headers(test_lib.h
DESTINATION test_lib)
lcmtypes_build() creates the .c/.h files from .lcm files and builds the lcmtypes_p1 library. Note that pods_install_* are just macroc to install() for a libraries, headers, executables. pods_use_pkg_config_packages(target dep1 dep2) executes include_directories(), target_link_libraries() and add_dependencies() after parsing pkg-config's output for dep1 and dep2. See lcmtypes.cmake for lcmtypes_build() and pods.cmake for these macros.
Update
I would draw your attention to lines 169 - 186 of lcmtypes.cmake. 169 adds a custom_target called lcmgen_c which is then added as dependency on libexample_msg.a.
I have a C project that has the following structure
Main/
Makefile.am
bin/
src/
Makefile.am
main.c
SomeLibrarySource/
SomeFuncs.c
SomeFuncs.h
The main.c contains the main function that uses functions defined in the SomeFuncs.{h/c} files.
I want to use autotools for this project. I read a couple of resources on autotools. But, I was only able to manage using autotools for a single level project where all source, object and other files reside in the same directory.
Then I got some links that talked about using autotools for deep projects like this one and then I got confused.
Right now I have two Makefile.am as follows
Makefile.am
SUBDIRS=src
src/Makefile.am
mainprgdir=../
mainprg_PROGRAMS=main
main_SOURCES=main.c
I am pretty sure that these files should not be as I have them now :P
How do I use autotools for the above project structure? (At least what should be there in those Makefile.am(s) and where should I place them.
EDIT:
One more thing! At the end I would like to have the object files created in the bin directory.
Thanks
mainprogdir=../ does not make a whole lot of sense (you don't know what it is relative to on installation). Probably intended:
# Main/Makefile.am
# .━━ target for `make install`
# |
# ↓ ↓━━ target for compilation
bin_PROGRAMS = bin/main
# ↓━━ based upon compilation target name
bin_main_SOURCES = src/main.c
There are two main approaches. If the functions in SomeLibrarySource are used only by main, then there's no need to build a separate library and you can simply specify the source files in src/Makefile.am
main_SOURCES = main.c SomeLibrarySource/SomeFuncs.c
However, if you actually want to use the functions in other code in your tree, you do not want to compile SomeFuncs.c multiple times but should use a convenience library.
# Assigning main_SOURCES is redundant
main_SOURCES = main.c
main_LDADD = SomeLibrarySource/libSomeFuncs.a
noinst_LIBRARIES = SomeLibrarySource/libSomeFuncs.a
AM_CPPFLAGS = -I$(srcdir)/SomeLibrarySource
(You'll need AC_PROG_RANLIB in configure.ac to use convenience libraries.)
If the source file is named SomeFuncs.c, automake will not need Makefile.am to specify SomeLibrarySource_libSomeFuncs_a_SOURCES, but if the name of the source code file does not match the name specified in noinst_LIBRARIES, SomeLibrarySource_libSomeFuncs_a_SOURCES should be set to the list of files used to build the library. Note that you do not need to specify main_SOURCES, since main.c is the default value if left unspecified (but it's not a bad idea to be explicit.) (In all of this, I am not comfortable use CamlCase names, but the system I'm using uses a case insensitive file system (biggest mistake apple ever made) and the examples I give here are working for me. YMMV)
You could of course do a recursive make, or build the library as a separate project and install it. (I like the final option. Libraries with useful features should exist on their own.)
I'm currently using recursive make and autotools and am looking to migrate to CMake for a project that looks something like this:
lx/ (project root)
src/
lx.c (contains main method)
conf.c
util/
str.c
str.h
etc.c
etc.h
server/
server.c
server.h
request.c
request.h
js/
js.c
js.h
interp.c
interp.h
bin/
lx (executable)
How should I go about this?
If there's never any source higher than the lx/src directory, then there's no need for the lx/CMakeLists.txt file. If there is, it should look something like this:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(lx)
add_subdirectory(src)
add_subdirectory(dir1)
add_subdirectory(dir2)
# And possibly other commands dealing with things
# directly in the "lx" directory
...where the subdirectories are added in library dependency order. Libraries that depend on nothing else should be added first, and then libraries that depend on those, and so on.
lx/src/CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(lx_exe)
add_subdirectory(util)
add_subdirectory(js)
add_subdirectory(server)
set(lx_source_files conf.c lx.c)
add_executable(lx ${lx_source_files})
target_link_libraries(lx server)
# also transitively gets the "js" and "util" dependencies
lx/src/util/CMakeLists.txt
set(util_source_files
etc.c
etc.h
str.c
str.h
)
add_library(util ${util_source_files})
lx/src/js/CMakeLists.txt
set(js_source_files
interp.c
interp.h
js.c
js.h
)
add_library(js ${js_source_files})
target_link_libraries(js util)
lx/src/server/CMakeLists.txt
set(server_source_files
request.c
request.h
server.c
server.h
)
add_library(server ${server_source_files})
target_link_libraries(server js)
# also transitively gets the "util" dependency
Then, in a command prompt:
mkdir lx/bin
cd lx/bin
cmake ..
# or "cmake ../src" if the top level
# CMakeLists.txt is in lx/src
make
By default, the lx executable will end up in the "lx/bin/src" directory using this exact layout. You can control what directory it ends up in by using the RUNTIME_OUTPUT_DIRECTORY target property and the set_property command.
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:RUNTIME_OUTPUT_DIRECTORY
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_property
Refer to target_link_libraries libs either by CMake target name, if the lib is built as a CMake target via add_library, or by full path to the library file otherwise.
See also, the output of "cmake --help-command target_link_libraries", or any other cmake command, and the full online documentation for cmake commands found here:
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Commands
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries
Steinberg VST3 library has a reusable method which recursively loops through subdirectories and adds them if they include a CMakeLists.txt file:
# add every sub directory of the current source dir if it contains a CMakeLists.txt
function(smtg_add_subdirectories)
file(GLOB subDirectories RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
foreach(dir ${subDirectories})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/CMakeLists.txt")
add_subdirectory(${dir})
endif()
endif()
endforeach(dir)
endfunction()
https://github.com/steinbergmedia/vst3_cmake/blob/master/modules/SMTG_AddSubDirectories.cmake