2

I am building a C Project and I'm currently a little lost on how to properly link in the libraries.

To summarize: I will have 3 projects that will have multiple executables. The projects will be using code from a library that will have multiple directories (sub-libraries). I have all the includes for the project in an includes directory. And I also will have a testing directory for the src and the lib as well.

How do I link in a library thats in a separate directory?

Is there a way to I can merge all these libraries into one main library, so I only have to link a single library?

The structure looks like this:

Project: |-- bin |-- build |-- src | |-- Project 1 | | |-- Project1a.c | | |-- Project1b.c | | |-- cmakelists.txt | |-- Project 2 | | |--Project2.c | |-- Project 3 | | |--Project3.c | |-- cmakelists.txt | |-- lib | |--Crypto_Lib | | |-- Crypto.c | | |-- cmakelists.txt | |--Communications_Lib | | |-- Communications.c | | |-- cmakelists.txt | |--Error_Lib | | |-- Error.c | | |-- cmakelists.txt | |--cmakelists.txt | |-- include | |--src | | |-- Project 1 | | | |-- Project1a.h | | | |-- Project1b.h | | |-- Project 2 | | | |-- Project2.h | | |-- Project 3 | | |-- Project3.h | |--lib | | |--Hash | | | |-- Crypto.h | | |--Communications | | | |-- Communications.h | | |--Error | | | |-- Error.h | |-- test | |--src (etc...) | |--lib (etc...) | |--cmakelists.txt | |--cmakelists.txt 

CMAKES I currently have:

~/CMakeLists.txt

 add_subdirectory(lib) add_subdirectory(src) add_subdirectory(test) 

~/lib/CMakeLists.txt

 #To access the header file include_directories(${CMAKE_SOURCE_DIR}/includes/lib) add_subdirectory(communications) add_subdirectory(crypto) add_subdirectory(error) 

~/src/CMakeLists.txt

 #To access the header file include_directories(${CMAKE_SOURCE_DIR}/includes/src) add_subdirectory(project_one) add_subdirectory(project_two) add_subdirectory(project_three) 

~/lib/communications/CMakeLists.txt

 add_library(Comm_Lib STATIC communications.c) 

~/lib/ crypto /CMakeLists.txt

 add_library(Crypto _Lib STATIC crypto.c) 

~/lib/error/CMakeLists.txt

 add_library(Error_Lib STATIC error.c) 

~/src/project_one/CMakeLists.txt

 add_executable(Project_1A Project_1a.c) add_executable(Project_1B Project_1B.c) #target_link_library(Project_1A Full_Library) Would like to be able to join all libraries together 

~/src/project_two/CMakeLists.txt

 add_executable(Project_Three Project_two.c) 

~/src/project_one/CMakeLists.txt

 add_executable(Project_Three Project_three.c) 

~/test/CMakeLists.txt

 add_subdirectory(lib_test) add_subdirectory(src_test) **Haven’t gotten any deeper in the test CMakeLists.txt 

I know I haven't used link_libraries yet, I'm just trying to figure out the best way to go about this.

Thanks for any help!

1 Answer 1

1

You almost got it: you can link your executables with the libraries defined in other directories. There is no problem with that.

add_executable(Project_1A Project_1a.c) add_executable(Project_1B Project_1B.c) target_link_library(Project_1A PUBLIC Full_Library) 

However, I would suggest you link only to the parts of the library you are using directly:

add_executable(Project_1A Project_1a.c) add_executable(Project_1B Project_1B.c) # Project_1A only use crypto directly in it's code target_link_library(Project_1A PUBLIC Crypto_Lib) # Project_1B use comm and error directly in it's code target_link_library(Project_1B PUBLIC Comm_Lib Error_Lib) 

Then instead of using the include_directories function, use the target_include_directories. There's an option to add the include directory as a usage requirement. That requirement will be propagated to other libraries which use this one:

target_include_directories(Comm_Lib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 

With that line above, anyone who links to Comm_Lib will have the communication library directory as include path.

If you really and to aggregate the three library together, Full_Library can be defined like this:

add_library(Full_Library INTERFACE) target_link_libraries(Full_Library INTERFACE Comm_Lib Crypto_Lib Error_Lib) target_include_directories(Full_Library INTERFACE common/include/dir) 
Sign up to request clarification or add additional context in comments.

6 Comments

In the cmakelist.txt for Project_1 , I tried adding the Comm Library for Project_1A, but I when I added communications.h into the project_1a.c, it was saying I couldn't find the file. Am I missing something? Also, what is the reason for including the PUBLIC? Thanks!
Also, say I have one more library (utility) that is used in the other libraries. How do I go about including them in the other libraries?
@AlexErling if you have include directories required tu use a particular library, you have to add it as an interface include directory. Let me edit
Okay, thanks for info. Last question being, which Cmakes do I do the target include in? In my example, is it ~/src/Cmakelist.txt, or whichever cmake will be used by the library? And I assume I need to do that for each library I add?
@AlexErling you can add a pure interface library that has the include dir: add_library(common INTERFACE) and add the include directory target_include_directory(common INTERFACE your/include/dir)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.