I have a project (static library) say of this form:
rootlib/
CMakeLists.txt (1)
src1.c
sublib1/
CMakeLists.txt (2)
subsrc1.c
sublib2/
CMakeLists.txt (3)
subsrc2.c
In all CMakeLists.txt I do add_library(... sources)
In (1) I also do target_link_libraries(rootlib sublib1 sublib2)
After make, I have three *.a files that are nowhere merged together. All I want to do now, is to create (automatically) a static library (i.e. merge everything).
You may use Cmake 2.8.8 with new feature - object library: http://www.cmake.org/Wiki/CMake/Tutorials/Object_Library
Or write by yourself via add_custom_target
Related
I have a submodule with a CMakeLists.txt, which I would like to "amend" in a way to make it work for my specific purpose (I need to add compiler flags and a different output directory) The output is a static library. My current approach is as follows:
I have a CMakeLists.txt in the root directory, which adds the submodule CMakeLists.txt via add_subdirectory() like so:
set(CMAKE_CXX_FLAGS "-my_needed_flags "
add_subdirectory(SubmoduleLibrary)
set_target_properties(SubmoduleLibrary PROPERTIES ARCHIVE_OUTPUT_DIRECTORY output_folder)
add_custom_target(BuildLib)
add_dependencies(BuildLib SubmoduleLibrary)
Now this seems to work in some ways (the output directory is correctly chosen). But I get linker errors which I don't get when I compile the library adding the flags etc to the original CMakeLists.txt.
What is the correct way to build a library from an existing CMakeLists.txt with added parameters?
I have a cmake project with many libraries (standalone additional packages) which are build within my project and then my project is linked against them.
If i have the following ...
CMakeLists.txt (1)
main.cpp
main.hpp
library/CMakeLists.txt (2)
library/dummy.cpp
library/dummy.hpp
... add have "add_definitions(-DMYDEF=15)" inside the library cmakelists (2). Can i somehow make this available to main.cpp and main.hpp, so they "see" the macro definition which is made inside the lib at preprocessing?
So not only sources/headers within the lib shall work with my definition but also any other dependency, like the main project with main.cpp/main.hpp
Yes, there is a way; use target_compile_definitions(mylib PUBLIC MYDEF=15) for your library, instead of add_definifions(-DMYDEF=15). That way all other targets that are linked against mylib will inherit compile definitions from mylib
Please note that target_compile_definitions should be added after the target is created, otherwise, you will receive the error.
Correct usage would be as follows:
#add library first
add_library(mylib)
#compile definitions for the target mylib
target_compile_definitions(
mylib
PUBLIC
MYDEF=15
)
More about the subject might be found in cmake documentation for target_compile_definitions
I am currently working on migrating from an internal build system to cmake, and I am enjoying it so far.
Our source code is broken up into discrete named components. These components generally will build a library and a set of executables. I have setup cmake with a base CMakeLists.txt and then created a CMakeLists.txt in each code component that is then included in the base. The component CMakeLists.txt have multiple targets in them, one for a library and then a variable number of executables.
With our current system you can type something like:
make component_name
and that will build a library and any executables associated with component_name. Is something like that possible with cmake? Can I use one name to build all of the targets in a CMakeLists.txt file?
First define a custom target, then define the dependencies of the target:
ADD_CUSTOM_TARGET(component_name)
ADD_DEPENDENCIES(component_name lib1 lib2 exe1 exe2)
I have a core library which branches off into several other libraries. In CMakeLists.txt it looks a bit like this
ADD_LIBRARY (core ...)
ADD_LIBRARY (branch1 ...)
ADD_LIBRARY (branch2 ...)
...
TARGET_LINK_LIBRARIES (branch1 core)
TARGET_LINK_LIBRARIES (branch2 core)
...
I have some executables which may depend on any or all of the branches. For those that depend on all the branches, instead of writing
ADD_EXECUTABLE (foo ...)
TARGET_LINK_LIBRARIES (foo branch1 branch2 ...)
I tried
ADD_LIBRARY (all-branches)
TARGET_LINK_LIBRARIES (all-branches branch1 branch2 ...)
then
TARGET_LINK_LIBRARIES (foo all-branches)
This works but CMake spits out a warning.
You have called ADD_LIBRARY for library all-branches without any source files. This typically indicates a problem with your CMakeLists.txt file
I understand the message, but it's not an error. What does CMake think is an acceptable way to build a meta-library like this?
I added a new type of library, the INTERFACE library to the upcoming CMake 3.0.0 release. That is designed as the solution to this problem:
http://www.cmake.org/cmake/help/git-master/manual/cmake-buildsystem.7.html#interface-libraries
add_library(all_branches INTERFACE)
target_link_libraries(all_branches INTERFACE branch1 branch2)
add_executable(myexe ...)
target_link_libraries(myexe all_branches)
In CMAKE the add_executable and add_library are very similar. They just tell to CMAKE that it should create a MAKE instruction for a library or executable based on the list of src files that you provide after the name of the library/executable and options (such as SHARED, etc).
What you can do is to add the names of your libs that you want to link in a name variable that you increase such as
SET(TARGET_LIBS ${TARGET_LIBS} myFirstLib)
SET(TARGET_LIBS ${TARGET_LIBS} myNextLib)
and then simply:
target_link_libraries(myExe ${TARGET_LIBS})
In this way you can easily define groups of libraries that may be needed for different sub projects without creating a meta-lib.
I am new to CMake and I am trying to get my project compiling. The project creates a few static libraries and a few executables.
Below is the example of the file structure that I have.
PROJECT
SRC
subProject_1
.cpp (all source files) and CMakeLists.txt 1 for this folder (creating a static library)
subproject_2
.cpp (all source files) and CMakeLists.txt 2 for this folder (creating a static library)
subproject_3
.cpp (all source files) and CMakeLists.txt 3 for this folder (creating the executable)
Include
subProject_1
.h (all the header files)
subProject_2
.h (all the header files)
subProject_3
.h (all the header files)
build/linux
CMakeLists.txt (Main CMakelist file)
Main CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
SET(CMAKE_CXX_COMPILER "g++")
Project(ort)
SET (CMAKE_CXX_FLAGS " -g -Wall -pThread")
#set the source and header directories location
set(ORT_HEADER_DIRECTORY "../../include") #include folder structure explained above
set(ORT_SOURCE_DIRECTORY "../../src")
set(ORT_BINARY_DIRECTORY "../../lib") # lib folder to contain all the libraries
set (CMAKE_CURRENT_BINARY_DIR ".")
#Include the library packages
include_directories("/usr/include/wx-2.8")
include_directories("/usr/local/cuda/include") and so on
#set the names of all the projects (for creating the libraries)
SET(PROJECT_NAMES "log" "data" "cc")
foreach(PROJECT_NAME ${PROJECT_NAMES})
# Create the cmake related files in the out folder so that the libraries can be
# copied to the lib folder
add_subdirectory( "{ORT_SOURCE_DIRECTORY}/${PROJECT_NAME}" "${CMAKE_CURRENT_BINARY_DIR}/out/${PROJECT_NAME}"
endforeach(PROJECT_NAME ${PROJECT_NAMES})
#set the names of all the projects (for creating the libraries)
SET(EXECUATALE_PROJECTS "metadata" )
foreach(EXECUATALE_PROJECT ${EXECUATALE_PROJECTS})
# Create the cmake related files in the out folder so that the libraries can be
# copied to the lib folder
add_subdirectory( "{ORT_SOURCE_DIRECTORY}/${EXECUATALE_PROJECT}" "${CMAKE_CURRENT_BINARY_DIR}/out/${EXECUATALE_PROJECT}"
endforeach(EXECUATALE_PROJECT ${EXECUATALE_PROJECTS})
CMakeLists.txt file for log directory (the same logic I have used for cc and data projects)
include_directories(${ORT_HEADER_DIRECTORY})
SET(LOG_SOURCE a.cpp b.cpp c.cpp)
ADD_LIBRARY(log_d ${LOG_SOURCE})
target_link)libraries(log_d cc_d data_d)
metadata CMakeLists.txt file (creating the executable project)
FIND_PACKAGE(wxWidgets)
IF(wxWidgets_FOUND)
INCLUDE(${wxWidgets_USE_FILE})
ENDIF(wxWidgets_FOUND)
Include_Directories(${wxWidgets_INCLUDE_DIRS})
include_directories(${ORT_HEADER_DIRECTORY})
include_directories("/usr/ort/lib/unixODBC/include")
SET(META_SOURCE meta.cpp data.cpp)
ADD_EXECUTABLE(meta_d ${META_SOURCE })
TARGET_LINK_LIBRARIES(meta_d log_d data_d)
When I just make the project, without the creation of the executables, static files are being generated. But, when I make the whole project (i.e. with the inclusion of the subProject_3 directory) I get undefined reference to a::String which is a function in a.cpp.
Note: All the 3 projects are dependent on each other. For example, in a.cpp, I have #include "b.h" and in b.cpp I have #include "a2.h".
So, I have few questions:
a) How do I resolve the undefined reference issue? Once I have generated the libraries for project 1 and 2, how do I link these to the executable?
b) Should I provide or add any dependencies when I am creating the static libraries? Is this the right way of creating the static libraries (as the projects are inter dependent)?
i.e. target_link_libraries(project1 project2 ...) in project 1 and target_link_libraries(project2 project1 ...) in project 2.
c) Every project needs to be compiled with its own compilation setting. Can you please let me know how can I specify the same for every individual project?
ERROR DETAILS:
Liking CXX executable metadata_d
../log/liblog_d.a: file not recognized: File truncated
collect2: ld returned 1 exit status
I also get the undefined reference error
/home...../metadata/data.cpp 172: undefined reference to xmlSerahNs
and so on.
collect2: ld returned 1 exit status
Thanks for the help.
How do I resolve the undefined reference issue ? Since, I have generating the libraries for project 1 and 2, how do I link these to the executable.
Just use target_link_libraries again, this time in subProject3's CMakeLists.txt:
target_link_libraries(subProject3 subProject2 subProject1)
Is this the right way of creating the static libraries (as the projects are inter dependent)
Yes. From the docs for target_link_libraries:
The library dependency graph is normally acyclic (a DAG), but in the
case of mutually-dependent STATIC libraries CMake allows the graph to
contain cycles (strongly connected components). When another target
links to one of the libraries CMake repeats the entire connected
component. For example, the code
add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)
links 'main' to 'A B A B'. (While one repetition is usually
sufficient, pathological object file and symbol arrangements can
require more. One may handle such cases by manually repeating the
component in the last target_link_libraries call. However, if two
archives are really so interdependent they should probably be combined
into a single archive.)
Every project needs to be compiled with there own compilation setting. Can you please let me know how can I specify the same for every individual project?
In the top-level CMakeLists.txt, before adding the subdirectories, you can set all the flags you need there. (see add_definitions and Properties on Targets for example) They will be adopted by all the subprojects unless specifically changed for a subproject.