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})
Related
Where would I go within CMakeLists.txt in order to change the name of the generated file?
For an executable target see target properties OUTPUT_NAME and SUFFIX. The actual output name if a combination of OUTPUT_NAME.SUFFIX with
OUTPUT_NAME defaulting to the target's name
SUFFIX defaulting to
whatever is defined in CMAKE_EXECUTABLE_SUFFIX for your platform (e.g. .exe on Windows platforms)
if the suffix is empty the compiler might add an extension (see Default file extension of the executable created by g++ under Cygwin vs Linux)
So the following example would override both defaults:
add_executable(a ...)
set_target_properties(
a
PROPERTIES
OUTPUT_NAME "myname"
SUFFIX ".myext"
)
Would generate myname.myext for target a.
For more details e.g. take a look at adding program suffix.
Here's a simple CMakeLists.txt
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(demo)
add_executable(hello hello.cpp)
This CMakeLists.txt compiles a hello.cpp file to an executable named hello. You can name the executable anything by using the add_executable statement.
add_executable(<executable-name> <source1> <source2> ...)
I use CMake to build a C project. Specifically, I use the following line:
configure_file(config.h.in config.h #ONLY)
this works fine as long as I build in the source directory. However, if I build elsewhere, the config.h file is created in /path/to/build/dir/config.h rather than in the source directory - and that's not part of the include path. How can I have CMake...
Ensure this specific file is included, or
Have the C compiler look both under the original source dir and under the build dir for include files?
There is an automatism for include directories with CMAKE_INCLUDE_CURRENT_DIR in CMake:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
If this variable is enabled, CMake automatically adds CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR to the include path for each directory.
So I prefer to individually have the following call on a need-by basis in my CMakeLists.txt:
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
Edit: Thanks for the hint of #zaufi, if your generated header file has a target scope then you should prefer (CMake >= Version 2.8.12) to make it only visible to that target (not globally to all targets) with:
target_include_directories(MyLibrary PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
Note: For source files with relative paths CMake looks in both directories CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR.
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)
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