This is my simple CMakeLists.txt
:
project(MyProject)
# Create the library from server.cpp
add_library(server OBJECT tcp_server.cpp tcp_server_priv.cpp)
# Add the current directory to the include path for this target
target_include_directories(server PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
# Create the executable from main.cpp and link it to the library
add_executable(my_server main.cpp $<TARGET_OBJECTS:server>)
I recently learned about the add_library(x OBJECT y z ...)
construct; my understanding: this doesn't create a static or shared library (.a or .so), but rather forms some temporary/logical grouping of object files, which can be referenced elsewhere as that same group. I.e. elsewhere, I can refer to $<TARGET_OBJECTS:server>
to refer to tcp_server.o and tcp_server_priv.o in aggregate, so the line add_executable(my_server main.cpp $<TARGET_OBJECTS:server>)
means "compile main.cpp, and link it with tcp_server.o and tcp_server_priv.o to make the executable my_server".
I.e. the add_executable
line does both compiling and linking.
I wanted my executable to also link with libpthread, so I tried making this change to the add_executable
line:
add_executable(my_server main.cpp $<TARGET_OBJECTS:server> pthread)
...but that generated this error with cmake:
-- Configuring done
CMake Error at src/CMakeLists.txt:9 (add_executable):
Cannot find source file:
pthread
Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
.hpp .hxx .in .txx
CMake Error at src/CMakeLists.txt:9 (add_executable):
No SOURCES given to target: med_server
CMake Generate step failed. Build files cannot be regenerated correctly.
make: *** [Makefile:160: cmake_check_build_system] Error 1
Isn't the above analogous to the following, where I compile main.cpp, link object-file dependencies, and libraries in a single g++
invocation:
// tcp_server.cpp
#include <iostream>
extern void private_func();
void public_func() {
std::cout << __FUNCTION__ << std::endl;
private_func();
}
// tcp_server_priv.cpp
#include <iostream>
void private_func() {
std::cout << __FUNCTION__ << std::endl;
}
// main.cpp
#include <semaphore.h>
extern void public_func();
int main(int argc, char* argv[]) {
sem_t my_sem;
public_func();
sem_init(&my_sem, 0, 0);
sem_destroy(&my_sem);
return 0;
}
$ g++ -c ./tcp_server.cpp \
> && g++ -c ./tcp_server_priv.cpp \
> && g++ main.cpp tcp_server.o tcp_server_priv.o -lpthread \
> && ./a.out
public_func
private_func
$
?
Why can I not link a library with the add_executable
statement when I can link object files?
Isn't the attempted add_executable(my_server main.cpp $<TARGET_OBJECTS:server> pthread)
effectively the same as g++ main.cpp tcp_server.o tcp_server_priv.o -lpthread
?