I can achieve this by gcc :
gcc -mwindows -o simple simple.c
But only find this in cmake:
add_executable(simple WIN32 simple.c)
But it's not exactly the same as -mwindows,
this will require the entry point to be WinMain,
while gcc -mwindows doesn't require this(can be main).
How should I do it properly?
If you use:
add_executable(simple WIN32 simple.c)
then you must provide a WinMain function. That's what the WIN32 flag to add_executable means: it means you're going to make it a Windows program, and provide a WinMain function.
I would recommend doing it this way if you're really writing a Windows application. It's what makes the most sense and fits most naturally with the underlying OS.
However, if you still want to pass gcc the "-mwindows" flag, but use a "main" anyway, then simply add "-mwindows" to the CMAKE_CXX_FLAGS and/or CMAKE_C_FLAGS value. You can do this in the cmake-gui program by adjusting those variables interactively to include "-mwindows" or you can do it with command line CMake, like this:
cmake -DCMAKE_C_FLAGS="-mwindows"
As DLRdave has said saying that the executable will be a win32 one means it will have WinMain as the entry point and be a windows application.
If the application is to be cross platform still then the usual means to suppress the console window but still allow use of main is to write a stub WinMain as found in the SDL or SFML libraries which simply calls the main function with the global variables __argc and __argv as arguments and returns its result.
This prevents the application from having a console window but reduces the disruption to the code of having to use WinMain as the entry point.
You can add target link option (for new versions of Cmake)
target_link_options(simple PRIVATE -mwindows)
https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/i386-and-x86_002d64-Windows-Options.html
In case you need it for both Windows and Linux
if (WIN32)
# /ENTRY:mainCRTStartup keeps the same "main" function instead of requiring "WinMain"
set(SUBSYSTEM_LINKER_OPTIONS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
else()
set(SUBSYSTEM_LINKER_OPTIONS "-mwindows")
endif()
target_link_options(TargetName PRIVATE ${SUBSYSTEM_LINKER_OPTIONS})
Related Question
Related
I currently want to create an installer with cmake, but don't add all necessary DLLs by myself to CMakeLists.txt. So one solution should be to use fixup_bundle, like here suggested, so hopefully he copy all DLLs, which he can detect with a dependency walker and are on path.
But currently I have no idea how is best way to use it on a target, following code won't work, because he don't resolve TARGET_FILE_DIR like if you are using add_custom_command. Do read location via get_property won't work too, because he don't know the target anymore at time of execution. Any idea?
INSTALL(CODE "
include(BundleUtilities)
fixup_bundle($<TARGET_FILE_DIR:${PROJECT_NAME}> \"\" \"D:\\Qt\")
" COMPONENT Runtime
)
If you are using Qt4, rather than using BundleUtilities directly, you may be better off using the DeployQt4 module. It includes the following three commands which may do what you need:
install_qt4_plugin_path
install_qt4_plugin
install_qt4_executable
If you are using Qt5, it gets a bit trickier. If you are only interested in Windows and/or Mac, then Qt itself provides an appropriate tool for handling/bringing across Qt's dependencies. The relevant tools are called windeployqt and macdeployqt respectively. Sadly, at time of writing, there is no linuxdeployqt tool yet that I'm aware of.
If neither of the above options are open to you or don't do what you need, then at least the DeployQt4 module gives some clues as to how you may be able to use the INSTALL(...) command like you attempted to. The DeployQt4 module uses the following for defining its target (see right near the end of the DeployQt4.cmake file):
FIXUP_QT4_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")"
${component}
)
The stuff in front of ${executable} is probably the bit you were missing. In your case, without seeing your full CMakeLists.txt file, I can only assume that you have a single target and it has the same name as your project (since you used ${PROJECT_NAME} in your attempted generator expression). You could try something like the following (not tested):
INSTALL(CODE "
include(BundleUtilities)
fixup_bundle(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MyTarget}\" \"\" \"D:\\Qt\")
" COMPONENT Runtime
)
where MyTarget is the name of the executable for your target (I think without any .exe suffix if you are on Windows). The DESTDIR part is needed when making packages, since CMake will redirect the install location by setting the DESTDIR environment variable (at least with some CMake generators). The CMAKE_INSTALL_PREFIX part is the path under which the application would be installed. There is some history behind this, but the above reflects the correct way of how to refer to the installed executable.
So I'm using CMake for a project.
It consists of a set of shared libraries linked to one executable. All are generated in the project (there are no external targets). Each sub project lives in its own directory, with its own cmakelists file.
So I make an out-of-source build, taking care to set CMAKE_BUILD_TYPE to Debug, and run cmake, and then make. I use GNU make 3.81, GCC 4.8.1, binutils 2.23.2 and CMake 3.2.3 on a Windows box using MSYS/MINGW.
The problem is that, when I load this executable in gdb (version 7.6), place a breakpoint on a function from one of the shared libraries, and then try to single step, gdb skips the whole function saying it has no line number information.
According to my understanding, line number information is a part of the debugging information, so I expected this to be generated during the compiling process (as per the CMAKE_BUILD_TYPE) which it didn't, so I would like to know how I can get CMake to generate this line number information properly (that is, without manually adding compiler-specific options in the cmake files, although I would take that if it's the only solution).
I've tried setting CMAKE_BUILD_TYPE from the command line (when invoking the cmake utility), inside the cmakelists, and even by modifying the CMakeCache.txt, and restarting the build from an empty directory with no success. I then made sure that CMAKE_BUILD_TYPE was effectively set to Debug by using the MESSAGE command to print it's value, and it was correctly set to Debug. So then I executed 'make VERBOSE=1' to see if the correct compiler option was added, and found it correctly used the "-g" option (although I would have expected -ggdb, but more on this later). The cmake documentation and Google did not bring me any answers.
My hypothesis is that the -g option only generates basic debugging information (such as the mappings between functions and their memory addresses, and how to access their arguments) whereas -ggdb would generate more in-detail debugging information in a gdb-specific format, including said line number informations), but a troubling fact is that, when running the executable in gdb, functions defined inside the executable do have line number information, only the shared libraries don't, hence my confusion.
I was trying to parallelize a Fortran program using MPI. I use CMake to do the build of my program. It was difficult to find support on getting CMake to create a working makefile for Fortran with MPI support on google, but from what I could gather, I added the following commands to my CMakeLists.txt script:
find_package(MPI REQUIRED)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_DIRS})
link_directories(${MPI_FortranLIBRARY_DIRS})
This will locate MPI on my system and then set the variables found in the following three commands. In my linking line, I added the MPI libraries variable to the list of the other libraries that my program needed to build.
target_link_libraries(${exe_name} otherlibs ${MPI_FortranLIBRARY_DIRS})
Doing cmake and then make worked to build the program and the program ran; however, when I tried to add more to the source which required me to include the mpif.h include file, my compilation failed due to not being able to find this header file. I also could not use mpi because the compiler cannot find the mpi.mod file in the path.
I inserted "message" commands into my CMakeLists.txt file and printed out the values of the variables that I was using for including and linking. It turns out that the variables, MPI_Fortran_INCLUDE_DIRS and MPI_FortranLIBRARY_DIRS weren't set to anything. A check of the module that CMake is actually using to set these variables (FindMPI.cmake) showed these variables to be non-existent. I changed my CMakeLists.txt file to use the correct variables:
find_package(MPI REQUIRED)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_PATH})
link_directories(${MPI_Fortran_LIBRARIES})
target_link_libraries(${exe_name} otherlibs ${MPI_Fortran_LIBRARIES})
Now when I execute make, the compiler could find both mpif.h as well as mpi.mod.
UPDATE:
I want to mention that this solution worked for cmake version 2.8.10.1. When I moved my CMakeLists.txt scripts to a different machine that has cmake version 2.8.4, I get the same error about mpi.mod missing during the link stage. I checked the FindMPI.cmake module and, sure enough, there are no variables that specify the language (i.e. there is no MPI_Fortran_LIBRARIES variable, just a MPI_LIBRARIES variable, and this variable is not getting set to the correct location of the mpi library on that system. So this solution will be dependent on cmake version.
Sounds like you are not using the mpi compiler. That is fine, but you have to add a lot of flags then. There is not really an mpi compiler but a wrapper that sets the flags to be able to use mpi. With cmake I was able to do this by defining the fortran compiler I was going to use BEFORE the call to cmake. It's not a nice solution since you loose portability, but it works. I'm trying to find a better solution and define inside cmake what compiler to use, but have not been able to do so. In other words, this works for me:
FC=mpif90 cmake ../.
make
I was having the same problem as you. Hope this solves the issue. If anybody finds how to define the fortran compiler INSIDE cmake please post it!
as you've already noticed, you misspelled the name of two variables, namely MPI_Fortran_LIBRARIES and MPI_Fortran_LIBRARIES
It is useful also to add:
cmake_minimum_required(VERSION 2.8.10)
at the very beginning of your CMake to be sure that these variables will be defined.
I'm just trying to set up a simple project that shall be able to compile on every platform, that is supported by CMake. I started my project on a Win7-system and wrote a little main.cpp that includes SDL.h and GL/glew.h. The style of the main-function is simple c++:
int main(int, char**) {}
In my CMakeLists.txt I call find_package(SDL) and find_package(GLEW). The CMake-part works well, so I just opened the vs10-solution-file and tried to compile when I get the LNK2019:
error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
This would mean that I chose the wrong subsystem, doesn't it? But if I simply toggle the subsystem from CONSOLE to WINDOWS and back the problem still exists. Has CMake set a hidden option for that? How can I compile my simple program in vs10?
I had this problem tonight. I'm using CMake to create an MSVC project to build my GLFW app. Of course, the age-old trick for getting rid of the console window if you're using MSVC by itself is to go in to the properties and set "Subsystem" to "Windows" and "Entry Point" to mainCRTStartup, which corresponds to adding the /SUBSYSTEM:WINDOWS /ENTRY:"mainCRTStartup" flags to link.exe, but CMake doesn't provide an easy way to do that.
If you just do a straight-up add_executable() command, you'll get /SUBSYSTEM:CONSOLE /ENTRY:"mainCRTStartup" being passed to the linker.
If you do an add_executable(exename WIN32 ...), you'll get /SUBSYSTEM:WINDOWS.
Gaah! Either option gets us halfway there!
I poked through the .cmake files that CMake ships with (fwiw, I'm using CMake 2.8.10 and Visual Studio 2012 Express), and discovered that the variable that seems to control the /SUBSYSTEM and /ENTRY flags is called CMAKE_CREATE_WIN32_EXE. So to set both parts, we just have to change that variable. Here's what I ended up with, which did the trick:
if(MSVC)
set(CMAKE_CREATE_WIN32_EXE "/SUBSYSTEM:WINDOWS /ENTRY:\"mainCRTStartup\"")
endif(MSVC)
Hope that helps someone else.
I'm wondering how i can make a portable build system (step-by-step), i currently use cmake because it was easy to set up in the first place, with only one arch target, but now that i have to package the library I'm developing I'm wondering how is the best way to make it portable for arch I'm testing.
I know I need a config.h to define things depending on the arch but I don't know how automatic this can be.
Any other way to have a build system are warmly welcome!
You can just use CMake, it's pretty straightforward.
You need these things:
First, means to find out the configuration specifics. For example, if you know that some function is named differently on some platform, you can use TRY_COMPILE to discover that:
TRY_COMPILE(HAVE_ALTERNATIVE_FUNC
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/alternative_function_test.cpp
CMAKE_FLAGS -DINCLUDE_DIRECTORIES=xxx
)
where alternative_function_test.cpp is a file in your source directory that compiles only with the alternative definition.
This will define variable HAVE_ALTERNATIVE_FUNC if the compile succeeds.
Second, you need to make this definition affect your sources. Either you can add it to compile flags
IF(HAVE_TR1_RANDOM)
ADD_DEFINITIONS(-DHAVE_TR1_RANDOM)
ENDIF(HAVE_TR1_RANDOM)
or you can make a config.h file. Create config.h.in with the following line
#cmakedefine HAVE_ALTERNATIVE_FUNCS
and create a config.h file by this line in CMakeLists.txt (see CONFIGURE_FILE)
CONFIGURE_FILE(config.h.in config.h #ONLY)
the #cmakedefine will be translated to #define or #undef depending on the CMake variable.
BTW, for testing edianness, see this mail
I have been using the GNU autoconf/automake toolchain which has worked well for me so far. I am only really focussed on Linux/x86 (and 64bit) and the Mac, which is important if you are building on a PowerPC, due to endian issues.
With autoconf you can check the host platform with the macro:
AC_CANONICAL_HOST
And check the endianness using:
AC_C_BIGENDIAN
Autoconf will then add definitions to config.h which you can use in your code.
I am not certain (have never tried) how well the GNU autotools work on Windows, so if Windows is one of your targets then you may be better off finding similar functionality with your existing cmake build system.
For a good primer on the autotools, have a look here:
http://www.freesoftwaremagazine.com/books/autotools_a_guide_to_autoconf_automake_libtool